#include <assert.h>
#include <stdio.h>

#include "../src/distribution.c"
#include "../src/qfunc.c"

typedef struct _LogPRatingTestDatum LogPRatingTestDatum ;
struct _LogPRatingTestDatum 
{ 
  struct
    {
      unsigned int      rating;
      double            alpha[4];
      double            logbeta;
    }                                   inputs;
  double                                desired_output;
};

static void
test_logprating (void)
{
  LogPRatingTestDatum data[] = 
    {{{3, {0.833249, 0.965062, 0.0882295, 0.148109}, 0.254743}, -1.04452}, {{2, {0.695449, 0.488398, 0.97021, 0.32168}, 0.664682}, -2.17304}, {{1, {0.228919, 0.708024, 0.889281, 0.512718}, 0.0933638}, -1.55832}, {{0, {0.138158, 0.925201, 0.375761, 0.949392}, 0.257005}, -0.894948}, {{0, {0.958452, 0.437078, 0.964528, 0.0474854}, 0.125202}, -1.88809}, {{3, {0.472016, 0.876298, 0.899376, 0.870459}, 0.776567}, -1.66853}, {{1, {0.387901, 0.929165, 0.54878, 0.111885}, 0.158982}, -1.95372}, {{1, {0.221142, 0.659499, 0.599167, 0.0656183}, 0.0829836}, -1.71996}, {{2, {0.734297, 0.223406, 0.116226, 0.825978}, 0.775846}, -0.81863}, {{2, {0.786328, 0.151698, 0.778493, 0.650643}, 0.314312}, -1.71195}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      auto double alphafunc (unsigned int);
      double alphafunc (unsigned int x) { return data[i].inputs.alpha[x]; }
      double output = logprating (data[i].inputs.rating,
                                  alphafunc,
                                  data[i].inputs.logbeta,
                                  4);

      assert (fabs (output - data[i].desired_output) <=
              1e-5 * (1 + fabs (output) + fabs (data[i].desired_output)) ||
              (fprintf (stderr, "%g ?= %g\n", output, data[i].desired_output),
               0));
    }
}

static void
test_dlogpratingdlogbeta (void)
{
  LogPRatingTestDatum data[] = 
    {{{3, {0.143241, 0.30918, 0.782666, 0.0217101}, 0.652013}, 0.323664}, {{1, {0.00659769, 0.448854, 0.116555, 0.737362}, 0.89627}, -0.699752}, {{3, {0.407064, 0.279119, 0.750552, 0.566001}, 0.417876}, -0.168126}, {{0, {0.108287, 0.395321, 0.41825, 0.798068}, 0.799897}, 0.45165}, {{0, {0.336108, 0.477524, 0.00174119, 0.39439}, 0.192867}, -0.0931007}, {{2, {0.168344, 0.219075, 0.37268, 0.540854}, 0.161746}, -0.0837997}, {{3, {0.77022, 0.256125, 0.803492, 0.265476}, 0.363157}, 0.234722}, {{0, {0.977006, 0.0529402, 0.699475, 0.945281}, 0.868719}, -1.63011}, {{1, {0.657619, 0.281225, 0.147213, 0.0688215}, 0.321511}, -0.073969}, {{1, {0.803702, 0.145472, 0.674431, 0.128644}, 0.635358}, 0.257961}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      auto double alphafunc (unsigned int);
      double alphafunc (unsigned int x) { return data[i].inputs.alpha[x]; }

      double output = dlogpratingdlogbeta (data[i].inputs.rating,
                                           alphafunc,
                                           data[i].inputs.logbeta,
                                           4);

      assert (fabs (output - data[i].desired_output) <=
              1e-5 * (1 + fabs (output) + fabs (data[i].desired_output)) ||
              (fprintf (stderr, "%g ?= %g\n", output, data[i].desired_output),
               0));
    }
}

typedef struct _DLogPRatingDalphaTestDatum DLogPRatingDalphaTestDatum;
struct _DLogPRatingDalphaTestDatum 
{
  struct
    {
      unsigned int      rating;
      double            alpha[4];
      double            logbeta;
    }                                   inputs;

  double                                desired_output[4];
};

static void
test_dlogpratingdalpha (void)
{
  DLogPRatingDalphaTestDatum data[] = 
    {{{1, {0.898961, 0.398726, 0.840596, 0.0715633}, 0.306289}, {0.190454, -0.982627, 0.206168, 0.586005}}, {{0, {0.65612, 0.44234, 0.512317, 0.128452}, 0.710759}, {-1.73675, 0.461693, 0.400398, 0.874655}}, {{3, {0.686444, 0.499408, 0.45617, 0.786126}, 0.293408}, {0.296566, 0.381108, 0.403858, -1.08153}}, {{2, {0.413459, 0.512822, 0.322883, 0.492526}, 0.485475}, {0.417843, 0.355543, -1.14085, 0.367464}}, {{3, {0.100536, 0.796945, 0.122953, 0.327046}, 0.201575}, {0.387433, 0.165274, 0.376953, -0.929661}}, {{1, {0.398219, 0.282357, 0.255483, 0.895286}, 0.742099}, {0.528104, -1.42674, 0.712719, 0.185914}}, {{1, {0.840017, 0.743166, 0.766834, 0.0313401}, 0.153574}, {0.201866, -0.939994, 0.219848, 0.51828}}, {{3, {0.243758, 0.310664, 0.245215, 0.860165}, 0.830298}, {0.740589, 0.635215, 0.738118, -2.11392}}, {{0, {0.797842, 0.922331, 0.36764, 0.344823}, 0.697306}, {-1.70566, 0.235721, 0.718132, 0.751806}}, {{0, {0.125387, 0.244686, 0.017777, 0.495731}, 0.727167}, {-1.47723, 0.46249, 0.739629, 0.275107}}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      auto double alphafunc (unsigned int);
      double alphafunc (unsigned int x) { return data[i].inputs.alpha[x]; }
      double dalpha[4];

      memset (dalpha, lrand48 (), 4 * sizeof (dalpha[0]));

      dlogpratingdalpha (dalpha,
                         data[i].inputs.rating,
                         alphafunc,
                         data[i].inputs.logbeta,
                         4);

      for (unsigned int j = 0; j < 4; ++j)
        {
          assert (fabs (dalpha[j] - data[i].desired_output[j]) <=
                  1e-5 * (1 + fabs (dalpha[j]) + fabs (data[i].desired_output[j])) ||
                  (fprintf (stderr, "%g ?= %g\n", dalpha[j], data[i].desired_output[j]),
                   0));
        }
    }
}

typedef struct _NormalDistributionTestDatum NormalDistributionTestDatum;
struct _NormalDistributionTestDatum 
{
  double mean;
  double stddev;
  double x;
  double desired_output;
  double desired_doutput;
};

static void
test_normaldistribution (void)
{
  NormalDistributionTestDatum data[] = 
    {{0.926397, 0.301751, 0.58779, -0.350384, 3.71875}, {0.473612, 0.156177, 0.0456262, -2.81705, 17.5467}, {0.784299, 0.208136, 0.79302, 0.649749, -0.201327}, {0.0686202, 0.731358, 0.50866, -0.787093, -0.822682}, {0.847739, 0.199902, 0.073739, -6.80483, 19.369}, {0.227435, 0.700526, 0.13108, -0.572474, 0.196347}, {0.752228, 0.423733, 0.555054, -0.168552, 1.09816}, {0.456649, 0.623583, 0.788376, -0.588161, -0.853083}, {0.628656, 0.154897, 0.0357929, -6.37867, 24.7096}, {0.314764, 0.47248, 0.109271, -0.263757, 0.920512}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      NormalDistribution p = normal_distribution (data[i].mean, data[i].stddev);

      double output = p.base.logpdf (data[i].x, &p.base);
      double doutput = p.base.dlogpdf (data[i].x, &p.base);

      assert (fabs (output - data[i].desired_output) <=
              1e-5 * (1 + fabs (output) + fabs (data[i].desired_output)) ||
              (fprintf (stderr, "%g ?= %g\n", output, data[i].desired_output),
               0));

      assert (fabs (doutput - data[i].desired_doutput) <=
              1e-5 * (1 + fabs (doutput) + fabs (data[i].desired_doutput)) ||
              (fprintf (stderr, "%g ?= %g\n", doutput, data[i].desired_doutput),
               0));
    }
}
        

typedef struct _QFuncTestDatum QFuncTestDatum ;
struct _QFuncTestDatum 
{ 
  struct
    {
      double    alpha[4 * 5 * 5];
      double    logbeta[3];
      double    gamma[5 * 5];
      double    pz[3 * 5];
      double    priorz[5];
      Rating    ratings[8];
      double    alphastddev;
      double    logbetamean;
      double    logbetastddev;
      double    gammamean;
      double    gammastddev;
    }                   inputs;
  double                desired_output;
};

static void
test_qfunc (void)
{
  QFuncTestDatum data[] = 
    {{{{0., 0.35263, 0.19596, 0.566488, 0.312946, 0.525559, 0., 0.45556,  0.696257, 0.88976, 0.293696, 0.212116, 0., 0.297084, 0.516435,  0.346644, 0.276515, 0.774408, 0., 0.494878, 0.0563925, 0.915546,  0.467236, 0.709764, 0., 0., 0.787252, 0.559734, 0.661911,  0.697587, 0.434622, 0., 0.363773, 0.0954234, 0.384641, 0.909063,  0.908213, 0., 0.399166, 0.494881, 0.615366, 0.696097, 0.102083,  0., 0.978446, 0.268722, 0.419582, 0.327675, 0.483568, 0., 0.,  0.21233, 0.504036, 0.860439, 0.773803, 0.425078, 0., 0.944302,  0.198527, 0.0762161, 0.990457, 0.580529, 0., 0.103104, 0.691575,  0.0813942, 0.672315, 0.703938, 0., 0.196694, 0.466028, 0.976218,  0.601855, 0.218248, 0., 0., 0.197306, 0.556636, 0.27418, 0.73468,  0.984976, 0., 0.0526003, 0.413742, 0.960877, 0.559897, 0.108298,  0., 0.215215, 0.884661, 0.56944, 0.527769, 0.112111, 0., 0.193086,  0.488046, 0.855454, 0.408173, 0.996392, 0.}, {0.0220184,  0.879236, 0.806318}, {1., 0.778144, 0.824713, 0.322599, 0.532138,  0.0434635, 1., 0.839737, 0.269999, 0.118396, 0.0825865, 0.27984,  1., 0.161701, 0.903181, 0.197925, 0.710399, 0.633932, 1., 0.79107,  0.00483947, 0.222353, 0.778478, 0.382897, 1.}, {0.0084476,  0.200335, 0.899242, 0.576579, 0.230304, 0.375622, 0.576643,  0.044441, 0.18684, 0.535885, 0.306644, 0.926045, 0.104254,  0.256045, 0.144943}, {0.0228643, 0.906328, 0.545646, 0.511011,  0.231794}, {{0, 1, 2}, {0, 0, 3}, {1, 0, 2}, {2, 0, 3}, {2, 1,  3}, {3, 0, 2}, {0, 1, 4}, {3, 0, 2}}, 0.901489, 0.323292,  0.732533, 0.848897,  0.893041}, -156.421}, {{{0., 0.122958, 0.833291, 0.272319,  0.662737, 0.747336, 0., 0.256648, 0.227878, 0.475897, 0.211451,  0.950004, 0., 0.301832, 0.371643, 0.955406, 0.805061, 0.278968,  0., 0.465315, 0.40976, 0.29405, 0.0471739, 0.563826, 0., 0.,  0.086468, 0.561516, 0.198277, 0.670785, 0.96351, 0., 0.728225,  0.925958, 0.00804766, 0.216175, 0.471577, 0., 0.69808, 0.53215,  0.00472375, 0.521573, 0.396248, 0., 0.160507, 0.0493178, 0.716512,  0.11728, 0.695192, 0., 0., 0.639557, 0.422462, 0.0701061,  0.131366, 0.553089, 0., 0.860945, 0.871829, 0.460581, 0.589579,  0.13272, 0., 0.945871, 0.452533, 0.373404, 0.661143, 0.247791, 0.,  0.920382, 0.36868, 0.13957, 0.851543, 0.759875, 0., 0., 0.319363,  0.423059, 0.734263, 0.0646834, 0.679805, 0., 0.000596984,  0.664157, 0.933318, 0.126716, 0.139652, 0., 0.792328, 0.472737,  0.537137, 0.00693147, 0.846456, 0., 0.0202043, 0.163733, 0.345788,  0.598665, 0.0998219, 0.}, {0.795053, 0.206218, 0.747122}, {1.,  0.339947, 0.47569, 0.783159, 0.0128588, 0.275263, 1., 0.795884,  0.782562, 0.348702, 0.341945, 0.669168, 1., 0.642911, 0.556374,  0.869208, 0.132031, 0.635979, 1., 0.709918, 0.849004, 0.968298,  0.290191, 0.111253, 1.}, {0.749182, 0.173245, 0.0839729, 0.364131,  0.409235, 0.697556, 0.300814, 0.351272, 0.133972, 0.901671,  0.518251, 0.00257067, 0.792027, 0.232503, 0.87534}, {0.446197,  0.922819, 0.100472, 0.239361,  0.736278}, {{1, 1, 1}, {3, 2, 1}, {2, 1, 1}, {3, 1, 1}, {2, 1,  2}, {0, 1, 2}, {0, 1, 2}, {2, 1, 4}}, 0.0738147, 0.132174,  0.94917, 0.625025,  0.324633}, -2999.27}, {{{0., 0.958929, 0.865197, 0.260894,  0.915397, 0.261373, 0., 0.564384, 0.909622, 0.781425, 0.359702,  0.0461327, 0., 0.907051, 0.989398, 0.127199, 0.170792, 0.460855,  0., 0.06658, 0.0267266, 0.931431, 0.724576, 0.992765, 0., 0.,  0.894553, 0.982261, 0.0995508, 0.668133, 0.935624, 0., 0.117064,  0.838657, 0.752735, 0.674251, 0.55268, 0., 0.929035, 0.97131,  0.314549, 0.506547, 0.0219835, 0., 0.981911, 0.187351, 0.335755,  0.561129, 0.915331, 0., 0., 0.160624, 0.404324, 0.836553,  0.922566, 0.266071, 0., 0.422063, 0.737002, 0.254434, 0.330447,  0.304999, 0., 0.898345, 0.501699, 0.656196, 0.752319, 0.969311,  0., 0.530389, 0.341647, 0.245772, 0.947327, 0.548477, 0., 0.,  0.154297, 0.910018, 0.386198, 0.633146, 0.993673, 0., 0.505694,  0.549646, 0.71058, 0.727602, 0.0836315, 0., 0.812644, 0.456146,  0.397154, 0.778632, 0.914298, 0., 0.954447, 0.740958, 0.0263129,  0.944988, 0.424059, 0.}, {0.39931, 0.78054, 0.99766}, {1.,  0.875582, 0.245014, 0.870523, 0.611462, 0.242436, 1., 0.251341,  0.364828, 0.0618162, 0.531856, 0.523739, 1., 0.281197, 0.249173,  0.0757103, 0.126585, 0.502565, 1., 0.334874, 0.121263, 0.385627,  0.476252, 0.389887, 1.}, {0.697204, 0.986317, 0.695711, 0.392226,  0.821623, 0.741304, 0.825189, 0.780765, 0.579187, 0.489963,  0.46036, 0.718948, 0.0473307, 0.966224, 0.179163}, {0.469776,  0.97162, 0.839638, 0.676598,  0.134902}, {{2, 2, 2}, {2, 0, 3}, {3, 2, 2}, {1, 0, 2}, {0, 1,  3}, {0, 2, 1}, {2, 1, 3}, {3, 1, 3}}, 0.850357, 0.454011,  0.200347, 0.745015,  0.153153}, -222.805}, {{{0., 0.467694, 0.504635, 0.352788,  0.331531, 0.72639, 0., 0.679447, 0.572024, 0.752344, 0.236428,  0.219087, 0., 0.853075, 0.705013, 0.270204, 0.0399236, 0.3833, 0.,  0.733393, 0.430566, 0.363325, 0.248398, 0.883035, 0., 0.,  0.976554, 0.162978, 0.503383, 0.729882, 0.508861, 0., 0.658343,  0.150595, 0.398351, 0.78247, 0.978896, 0., 0.578571, 0.646008,  0.546043, 0.759809, 0.725496, 0., 0.940995, 0.275839, 0.719886,  0.342196, 0.207602, 0., 0., 0.845273, 0.356561, 0.0937982,  0.324567, 0.868719, 0., 0.193582, 0.590415, 0.594685, 0.359858,  0.535239, 0., 0.43982, 0.196333, 0.577388, 0.556343, 0.861248, 0.,  0.550326, 0.0313452, 0.796534, 0.135752, 0.609331, 0., 0.,  0.755507, 0.0766481, 0.793556, 0.40173, 0.910234, 0., 0.720088,  0.699758, 0.0771629, 0.0415151, 0.526506, 0., 0.109343, 0.482478,  0.681657, 0.991266, 0.669523, 0., 0.286145, 0.104269, 0.434923,  0.808275, 0.735819, 0.}, {0.0729242, 0.638389, 0.672523}, {1.,  0.126487, 0.317417, 0.561741, 0.878967, 0.724758, 1., 0.407184,  0.841654, 0.179209, 0.647595, 0.365669, 1., 0.315148, 0.0698658,  0.165117, 0.684012, 0.323882, 1., 0.400342, 0.878972, 0.579742,  0.888959, 0.592067, 1.}, {0.143153, 0.506818, 0.250569, 0.919545,  0.016666, 0.1894, 0.688828, 0.0405779, 0.291908, 0.782217,  0.847174, 0.861369, 0.644313, 0.416548, 0.532026}, {0.791503,  0.479197, 0.732536, 0.208144,  0.391161}, {{3, 2, 4}, {2, 1, 1}, {2, 0, 1}, {1, 2, 0}, {1, 1,  1}, {0, 0, 0}, {3, 1, 0}, {1, 2, 4}}, 0.600225, 0.152794,  0.319186, 0.799094,  0.457071}, -139.929}, {{{0., 0.645976, 0.0686164, 0.879549,  0.440405, 0.456576, 0., 0.379789, 0.838971, 0.148497, 0.674359,  0.532614, 0., 0.977602, 0.504184, 0.257811, 0.000588258, 0.186099,  0., 0.0249867, 0.525275, 0.792444, 0.794938, 0.424762, 0., 0.,  0.372481, 0.473258, 0.995844, 0.967691, 0.726504, 0., 0.404642,  0.116295, 0.527285, 0.269928, 0.0248535, 0., 0.277324, 0.378788,  0.595569, 0.492239, 0.299722, 0., 0.874605, 0.337758, 0.491651,  0.113623, 0.849618, 0., 0., 0.812483, 0.699207, 0.318685,  0.424856, 0.440002, 0., 0.225948, 0.322841, 0.457165, 0.713498,  0.821306, 0., 0.206546, 0.92988, 0.443569, 0.796453, 0.929222, 0.,  0.551092, 0.848, 0.304214, 0.6295, 0.676487, 0., 0., 0.510243,  0.812563, 0.515877, 0.826869, 0.69776, 0., 0.113356, 0.197191,  0.402013, 0.257758, 0.887407, 0., 0.87435, 0.944847, 0.54426,  0.0661008, 0.667805, 0., 0.0149673, 0.100691, 0.269648, 0.738583,  0.463876, 0.}, {0.25269, 0.965434, 0.109084}, {1., 0.787389,  0.742448, 0.152872, 0.593207, 0.96052, 1., 0.0446879, 0.0395159,  0.396016, 0.558507, 0.78693, 1., 0.152109, 0.521665, 0.61366,  0.24267, 0.0860079, 1., 0.853861, 0.598693, 0.141979, 0.81636,  0.115277, 1.}, {0.134817, 0.889289, 0.850926, 0.00619342,  0.347428, 0.146841, 0.698054, 0.412986, 0.386908, 0.102153,  0.658538, 0.0169702, 0.828401, 0.315223, 0.506429}, {0.495305,  0.214741, 0.072553, 0.420421,  0.641444}, {{0, 0, 4}, {0, 2, 1}, {0, 0, 3}, {2, 1, 0}, {1, 2,  2}, {1, 0, 4}, {1, 1, 3}, {3, 0, 0}}, 0.616049, 0.930574,  0.604062, 0.526167,  0.481232}, -139.623}, {{{0., 0.0412854, 0.753136, 0.519974,  0.133804, 0.894445, 0., 0.0550821, 0.106987, 0.746895, 0.792292,  0.396544, 0., 0.0900173, 0.918494, 0.477069, 0.890115, 0.594712,  0., 0.703753, 0.404516, 0.469693, 0.953268, 0.0877047, 0., 0.,  0.473942, 0.865632, 0.427101, 0.606473, 0.432657, 0., 0.112496,  0.907128, 0.472669, 0.538212, 0.0574138, 0., 0.80014, 0.725774,  0.74592, 0.66087, 0.710123, 0., 0.80728, 0.268851, 0.770755,  0.11541, 0.103526, 0., 0., 0.864335, 0.301062, 0.162142,  0.0158216, 0.390392, 0., 0.43543, 0.735041, 0.409349, 0.957736,  0.322934, 0., 0.827913, 0.936679, 0.419523, 0.26552, 0.0277733,  0., 0.210905, 0.673603, 0.60465, 0.31765, 0.403625, 0., 0.,  0.404752, 0.833896, 0.20224, 0.300099, 0.540418, 0., 0.532834,  0.040098, 0.284277, 0.150025, 0.0974042, 0., 0.305057, 0.874929,  0.19229, 0.77447, 0.477144, 0., 0.93825, 0.772766, 0.50895,  0.44937, 0.727345, 0.}, {0.0991631, 0.9043, 0.13172}, {1.,  0.323719, 0.694411, 0.0704042, 0.92948, 0.0236204, 1., 0.153993,  0.53757, 0.889382, 0.739343, 0.00396781, 1., 0.440166, 0.584325,  0.864414, 0.811678, 0.665696, 1., 0.107181, 0.926164, 0.0389116,  0.156746, 0.657811, 1.}, {0.198819, 0.939749, 0.252446, 0.526091,  0.8751, 0.245338, 0.182042, 0.596611, 0.85148, 0.0913446,  0.644471, 0.707229, 0.112137, 0.0873768, 0.204305}, {0.122904,  0.247722, 0.275699, 0.53861,  0.0157226}, {{0, 1, 4}, {2, 1, 4}, {2, 1, 3}, {2, 1, 2}, {2, 2,  0}, {0, 2, 2}, {1, 2, 4}, {2, 1, 0}}, 0.321558, 0.236787,  0.381864, 0.357912,  0.122739}, -306.338}, {{{0., 0.297039, 0.129418, 0.831821,  0.247639, 0.0517009, 0., 0.947376, 0.23521, 0.396159, 0.960356,  0.302905, 0., 0.527982, 0.284023, 0.872979, 0.0985994, 0.405078,  0., 0.0363003, 0.597281, 0.55999, 0.389355, 0.714742, 0., 0.,  0.360494, 0.178126, 0.0314433, 0.592003, 0.0634548, 0., 0.048708,  0.199622, 0.344364, 0.0117539, 0.101332, 0., 0.964412, 0.948205,  0.0513976, 0.798427, 0.43643, 0., 0.664182, 0.178418, 0.699828,  0.0313524, 0.627882, 0., 0., 0.581137, 0.139838, 0.641997,  0.91314, 0.220644, 0., 0.961712, 0.610554, 0.321137, 0.157189,  0.913004, 0., 0.410932, 0.976772, 0.145435, 0.811672, 0.44652, 0.,  0.0285671, 0.0940376, 0.0132452, 0.01009, 0.364385, 0., 0.,  0.91562, 0.313418, 0.978738, 0.736503, 0.334482, 0., 0.17358,  0.33674, 0.823363, 0.113838, 0.211868, 0., 0.726186, 0.502226,  0.956649, 0.298864, 0.315254, 0., 0.525454, 0.811214, 0.487192,  0.868734, 0.496887, 0.}, {0.717176, 0.473946, 0.858644}, {1.,  0.132502, 0.801557, 0.160529, 0.879907, 0.395999, 1., 0.467075,  0.986949, 0.543166, 0.572637, 0.353237, 1., 0.775081, 0.81698,  0.0704106, 0.396587, 0.476217, 1., 0.501726, 0.544957, 0.585374,  0.989026, 0.632991, 1.}, {0.04807, 0.868197, 0.515079, 0.774347,  0.915568, 0.0666405, 0.354551, 0.89444, 0.519568, 0.599566,  0.367602, 0.351274, 0.946932, 0.246329, 0.592521}, {0.534294,  0.876521, 0.849742, 0.116303,  0.0325683}, {{3, 1, 3}, {1, 0, 4}, {0, 1, 4}, {3, 2, 1}, {1, 1,  4}, {3, 1, 4}, {0, 0, 1}, {0, 1, 0}}, 0.331564, 0.264368,  0.127277, 0.399577,  0.283494}, -217.619}, {{{0., 0.396171, 0.612198, 0.62523, 0.367927,  0.329531, 0., 0.257647, 0.730789, 0.848358, 0.729965, 0.890046,  0., 0.379515, 0.901426, 0.483635, 0.297525, 0.845221, 0.,  0.0249051, 0.633894, 0.181222, 0.812653, 0.693341, 0., 0.,  0.369525, 0.0539445, 0.413076, 0.409846, 0.973354, 0., 0.441747,  0.787846, 0.0419198, 0.643824, 0.184099, 0., 0.0570572, 0.193562,  0.913859, 0.294054, 0.677542, 0., 0.292136, 0.430223, 0.996529,  0.832321, 0.26723, 0., 0., 0.79633, 0.815307, 0.0196684, 0.57389,  0.426805, 0., 0.761362, 0.606592, 0.164043, 0.45345, 0.319616, 0.,  0.818746, 0.122124, 0.809627, 0.135516, 0.761689, 0., 0.928562,  0.895768, 0.841463, 0.0841467, 0.636426, 0., 0., 0.465545,  0.844934, 0.251826, 0.369196, 0.669215, 0., 0.0296272, 0.232157,  0.795306, 0.242411, 0.268265, 0., 0.625565, 0.631263, 0.78896,  0.948649, 0.806819, 0., 0.509139, 0.979333, 0.813133, 0.0451297,  0.580577, 0.}, {0.0835649, 0.97167, 0.960983}, {1., 0.944151,  0.61802, 0.126736, 0.709157, 0.574955, 1., 0.948805, 0.0971086,  0.477, 0.779649, 0.706394, 1., 0.828844, 0.851436, 0.148387,  0.917434, 0.880195, 1., 0.044617, 0.639248, 0.938101, 0.0670619,  0.999487, 1.}, {0.0586703, 0.854536, 0.095392, 0.0385043,  0.114519, 0.236516, 0.968656, 0.329347, 0.539564, 0.287711,  0.871548, 0.852347, 0.759915, 0.581317, 0.0427038}, {0.000911174,  0.611528, 0.663883, 0.162509,  0.956294}, {{2, 0, 0}, {0, 1, 2}, {3, 0, 1}, {2, 2, 0}, {0, 0,  3}, {2, 1, 1}, {1, 1, 1}, {3, 2, 4}}, 0.972281, 0.725782,  0.0954474, 0.956807,  0.91361}, -198.932}, {{{0., 0.871246, 0.0000553994, 0.918303,  0.799091, 0.63473, 0., 0.0313993, 0.588956, 0.259527, 0.347019,  0.159852, 0., 0.736609, 0.499612, 0.765702, 0.117148, 0.735698,  0., 0.888084, 0.101819, 0.954639, 0.779404, 0.915803, 0., 0.,  0.376037, 0.859191, 0.822597, 0.00219306, 0.504791, 0., 0.859136,  0.904294, 0.203102, 0.870061, 0.827737, 0., 0.315338, 0.943575,  0.523042, 0.667885, 0.57873, 0., 0.443963, 0.75734, 0.550737,  0.843032, 0.555879, 0., 0., 0.655521, 0.596098, 0.0636282,  0.640075, 0.279484, 0., 0.736907, 0.241032, 0.637882, 0.774693,  0.877771, 0., 0.336738, 0.43478, 0.904633, 0.0500343, 0.0213992,  0., 0.491205, 0.38159, 0.382149, 0.44267, 0.0472425, 0., 0.,  0.62425, 0.831412, 0.599638, 0.491364, 0.968729, 0., 0.235314,  0.53601, 0.851288, 0.689245, 0.498407, 0., 0.294978, 0.213406,  0.914551, 0.620637, 0.95824, 0., 0.778625, 0.00991863, 0.570602,  0.936841, 0.28742, 0.}, {0.628328, 0.188453, 0.494172}, {1.,  0.240178, 0.00407787, 0.35704, 0.894534, 0.748814, 1., 0.0353489,  0.121726, 0.358524, 0.897526, 0.346104, 1., 0.623319, 0.0635458,  0.68412, 0.431553, 0.00268222, 1., 0.105305, 0.905495, 0.421634,  0.43208, 0.168464, 1.}, {0.618075, 0.793306, 0.243627, 0.674293,  0.377897, 0.789228, 0.886587, 0.779759, 0.629083, 0.75388,  0.764861, 0.421235, 0.731558, 0.407775, 0.141542}, {0.357689,  0.0474376, 0.976222, 0.13886,  0.252384}, {{2, 2, 1}, {2, 1, 3}, {0, 2, 4}, {1, 1, 3}, {0, 0,  1}, {2, 0, 2}, {2, 1, 3}, {1, 0, 1}}, 0.141943, 0.554588,  0.70678, 0.0839198,  0.523869}, -878.938}, {{{0., 0.761282, 0.463153, 0.409627,  0.145972, 0.972053, 0., 0.576566, 0.629868, 0.516888, 0.218174,  0.811705, 0., 0.208633, 0.785331, 0.810398, 0.670163, 0.850943,  0., 0.737893, 0.834176, 0.531304, 0.598559, 0.59595, 0., 0.,  0.279588, 0.824524, 0.51464, 0.0720816, 0.518307, 0., 0.361372,  0.105012, 0.92611, 0.546254, 0.784806, 0., 0.475144, 0.409222,  0.32808, 0.973101, 0.266512, 0., 0.623891, 0.517682, 0.302937,  0.415568, 0.885997, 0., 0., 0.683506, 0.771633, 0.817009,  0.290047, 0.403917, 0., 0.947109, 0.302369, 0.217966, 0.885611,  0.585737, 0., 0.197357, 0.291856, 0.339357, 0.800931, 0.722212,  0., 0.882634, 0.0112772, 0.827831, 0.455701, 0.258743, 0., 0.,  0.493595, 0.524894, 0.0401326, 0.372746, 0.81009, 0., 0.753261,  0.223124, 0.0826987, 0.406172, 0.806152, 0., 0.920755, 0.864733,  0.520562, 0.220414, 0.723398, 0., 0.572878, 0.181204, 0.419483,  0.00118607, 0.690244, 0.}, {0.169927, 0.591652, 0.545485}, {1.,  0.4315, 0.676332, 0.0667585, 0.505353, 0.0587544, 1., 0.866242,  0.313498, 0.282229, 0.976056, 0.46007, 1., 0.507346, 0.361474,  0.111322, 0.939508, 0.286932, 1., 0.638076, 0.538445, 0.758304,  0.867449, 0.63689, 1.}, {0.848201, 0.588377, 0.275797, 0.0914043,  0.416701, 0.912045, 0.209038, 0.586051, 0.357946, 0.045803,  0.89554, 0.303823, 0.381891, 0.585733, 0.388194}, {0.942348,  0.270568, 0.646225, 0.101262,  0.304273}, {{3, 0, 2}, {2, 0, 1}, {1, 2, 2}, {3, 2, 3}, {2, 2,  3}, {0, 2, 3}, {2, 2, 4}, {2, 0, 1}}, 0.732123, 0.887921,  0.233813, 0.667383, 0.883922}, -154.493}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      ParameterizedNormalDistribution prior_alpha = 
        parameterized_normal_distribution (data[i].inputs.alphastddev);
      NormalDistribution prior_logbeta = 
        normal_distribution (data[i].inputs.logbetamean, 
                             data[i].inputs.logbetastddev);
      NormalDistribution prior_gamma = 
        normal_distribution (data[i].inputs.gammamean,
                             data[i].inputs.gammastddev);

      for (unsigned int j = 0; j < 4; ++j)
        {
          for (unsigned int k = 0; k < 5; ++k)
            {
              data[i].inputs.alpha[j * 5 * 5 + k * 5 + k] = drand48 ();
            }
        }

      for (unsigned int k = 0; k < 5; ++k)
        {
          data[i].inputs.gamma[k * 5 + k] = drand48 ();
        }

      double output = qfunc (data[i].inputs.alpha,
                             4,
                             5,
                             data[i].inputs.logbeta,
                             3,
                             data[i].inputs.gamma,
                             data[i].inputs.pz,
                             data[i].inputs.priorz,
                             data[i].inputs.ratings,
                             8,
                             &prior_alpha.base,
                             &prior_logbeta.base,
                             &prior_gamma.base,
                             0);

      assert (fabs (output - data[i].desired_output) <=
              1e-5 * (1 + fabs (output) + fabs (data[i].desired_output)) ||
              (fprintf (stderr, "%g ?= %g\n", output, data[i].desired_output),
               0));
    }
}

static void
test_qfunc_symmetric (void)
{
  QFuncTestDatum data[] = 
    {{{{0., 0.299545, 0.958016, 0.575979, 0.467221, 0.3875, 0., 0.748978,  0.989927, 0.109275, 0.341697, 0.853437, 0., 0.686105, 0.727384,  0.755963, 0.465243, 0.743756, 0., 0.456816, 0.109738, 0.363981,  0.439484, 0.724692, 0., 0., 0.221817, 0.130168, 0.772101, 0.84077,  0.922272, 0., 0.172152, 0.196122, 0.373549, 0.534772, 0.423174,  0., 0.206195, 0.264274, 0.193076, 0.569737, 0.52009, 0., 0.53689,  0.437112, 0.104494, 0.776334, 0.0800743, 0., 0., 0.327374,  0.740513, 0.33685, 0.355382, 0.105557, 0., 0.610345, 0.56475,  0.514612, 0.183285, 0.438193, 0., 0.368628, 0.141063, 0.648513,  0.0150185, 0.162433, 0., 0.876789, 0.455437, 0.445282, 0.642343,  0.339899, 0., 0., 0.0183245, 0.340788, 0.86601, 0.259825, 0.69095,  0., 0.600275, 0.529159, 0.904443, 0.585393, 0.989931, 0.,  0.96441, 0.389831, 0.402108, 0.551738, 0.595782, 0., 0.248768,  0.753595, 0.53672, 0.433349, 0.371978, 0.}, {0.298158, 0.091438,  0.791006}, {1., 0.0320792, 0.279834, 0.75065, 0.924996, 0.772254,  1., 0.588884, 0.150375, 0.395837, 0.867812, 0.00349071, 1.,  0.160444, 0.431427, 0.477981, 0.601383, 0.608706, 1., 0.835645,  0.229213, 0.847787, 0.0719859, 0.402296, 1.}, {0.857235, 0.549629,  0.980548, 0.61129, 0.825156, 0.269795, 0.229898, 0.686293,  0.0529013, 0.680911, 0.0795233, 0.290456, 0.18509, 0.677421,  0.91908}, {0.859029, 0.707109, 0.0760377, 0.310374,  0.0233847}, {{3, 1, 4}, {1, 0, 4}, {0, 2, 0}, {2, 2, 1}, {2, 1,  3}, {1, 2, 4}, {0, 1, 2}, {0, 1, 0}}, 0.477896, 0.22825,  0.238388, 0.621089,  0.620661}, -149.856}, {{{0., 0.678621, 0.25784, 0.00979926,  0.795505, 0.408826, 0., 0.0279423, 0.323506, 0.742604, 0.727915,  0.948419, 0., 0.0330494, 0.557514, 0.0504946, 0.0293395, 0.17402,  0., 0.850405, 0.974457, 0.718966, 0.150635, 0.372509, 0., 0.,  0.746207, 0.480578, 0.529546, 0.751848, 0.0675853, 0., 0.222737,  0.519747, 0.956343, 0.658759, 0.194795, 0., 0.196241, 0.213739,  0.930844, 0.246376, 0.163192, 0., 0.656225, 0.880349, 0.217037,  0.989172, 0.805819, 0., 0., 0.905892, 0.498071, 0.838537, 0.43331,  0.159686, 0., 0.0174935, 0.30899, 0.681462, 0.0921005, 0.794756,  0., 0.789243, 0.725119, 0.433342, 0.599961, 0.593002, 0., 0.51138,  0.502498, 0.353585, 0.429811, 0.855155, 0., 0., 0.622149,  0.136548, 0.440639, 0.049336, 0.716256, 0., 0.638477, 0.602102,  0.616026, 0.55657, 0.620984, 0., 0.293112, 0.934564, 0.46447,  0.826228, 0.503869, 0., 0.209445, 0.0311284, 0.226267, 0.910866,  0.698065, 0.}, {0.528631, 0.872682, 0.481055}, {1., 0.84291,  0.906482, 0.736133, 0.0404164, 0.793574, 1., 0.190226, 0.0976561,  0.438314, 0.177548, 0.633655, 1., 0.476672, 0.145202, 0.242984,  0.169185, 0.650444, 1., 0.641333, 0.0335385, 0.138057, 0.424178,  0.730467, 1.}, {0.335473, 0.609426, 0.551496, 0.249412, 0.492563,  0.702944, 0.815362, 0.208995, 0.698989, 0.512718, 0.717706,  0.770681, 0.521441, 0.879063, 0.241034}, {0.625479, 0.278457,  0.709878, 0.590589,  0.984146}, {{1, 0, 2}, {0, 0, 4}, {2, 0, 0}, {2, 0, 0}, {1, 2,  2}, {2, 2, 2}, {3, 0, 0}, {0, 2, 1}}, 0.244918, 0.571821,  0.166412, 0.253679,  0.909445}, -287.185}, {{{0., 0.962395, 0.614916, 0.00426661,  0.416882, 0.25945, 0., 0.799554, 0.795271, 0.717893, 0.746732,  0.0818474, 0., 0.0245897, 0.196453, 0.867669, 0.840813, 0.39911,  0., 0.917996, 0.157791, 0.250224, 0.414964, 0.673078, 0., 0.,  0.58597, 0.0838122, 0.161286, 0.763632, 0.623575, 0., 0.468896,  0.157019, 0.34675, 0.364125, 0.669343, 0., 0.361748, 0.628857,  0.617393, 0.587495, 0.337158, 0., 0.432404, 0.749724, 0.746682,  0.938048, 0.514408, 0., 0., 0.591933, 0.496458, 0.523084, 0.84133,  0.00596343, 0., 0.412646, 0.361798, 0.0776979, 0.382388,  0.943749, 0., 0.204779, 0.730948, 0.0182631, 0.274407, 0.843031,  0., 0.102091, 0.40087, 0.686912, 0.505872, 0.669687, 0., 0.,  0.651146, 0.94023, 0.567824, 0.155279, 0.0592124, 0., 0.443772,  0.0447402, 0.313949, 0.0532489, 0.0311264, 0., 0.682942, 0.236251,  0.670861, 0.087377, 0.478164, 0., 0.505303, 0.652598, 0.81297,  0.635133, 0.403212, 0.}, {0.251728, 0.126059, 0.129261}, {1.,  0.733525, 0.600582, 0.185829, 0.561437, 0.578246, 1., 0.541369,  0.742057, 0.516697, 0.264297, 0.488121, 1., 0.710931, 0.833754,  0.0280457, 0.81726, 0.623553, 1., 0.355591, 0.522743, 0.164662,  0.810583, 0.720458, 1.}, {0.119531, 0.912934, 0.684525, 0.591197,  0.386006, 0.312353, 0.498696, 0.02976, 0.80776, 0.770983,  0.756639, 0.513063, 0.543464, 0.282862, 0.0457082}, {0.679309,  0.515418, 0.465603, 0.422155,  0.323718}, {{0, 0, 0}, {1, 2, 4}, {2, 1, 1}, {0, 0, 4}, {0, 0,  3}, {3, 0, 2}, {3, 0, 2}, {0, 1, 0}}, 0.992675, 0.300941,  0.611571, 0.603261,  0.873145}, -168.343}, {{{0., 0.388006, 0.927047, 0.0120637,  0.487139, 0.0756538, 0., 0.428351, 0.982304, 0.679378, 0.304671,  0.671713, 0., 0.46924, 0.135915, 0.0218082, 0.626005, 0.789931,  0., 0.620497, 0.556205, 0.20385, 0.466213, 0.627821, 0., 0.,  0.255265, 0.592278, 0.862952, 0.754676, 0.867258, 0., 0.665231,  0.850889, 0.267538, 0.791605, 0.23688, 0., 0.868585, 0.588159,  0.486934, 0.565167, 0.399345, 0., 0.452244, 0.465126, 0.939163,  0.609414, 0.831748, 0., 0., 0.90892, 0.735313, 0.143201, 0.203927,  0.653656, 0., 0.143035, 0.280248, 0.44925, 0.786397, 0.477803,  0., 0.42936, 0.181713, 0.994793, 0.240923, 0.560775, 0., 0.593554,  0.507859, 0.675756, 0.16143, 0.141309, 0., 0., 0.042733,  0.736593, 0.552016, 0.309561, 0.133813, 0., 0.00128052, 0.408816,  0.105635, 0.480157, 0.858246, 0., 0.128567, 0.656384, 0.69376,  0.380443, 0.699208, 0., 0.474671, 0.698968, 0.139519, 0.138433,  0.881118, 0.}, {0.191109, 0.463763, 0.977003}, {1., 0.739808,  0.148376, 0.72717, 0.424987, 0.430247, 1., 0.0145631, 0.725889,  0.0161716, 0.324612, 0.534406, 1., 0.867643, 0.887604, 0.668228,  0.840646, 0.487201, 1., 0.188397, 0.193557, 0.141678, 0.347681,  0.0499634, 1.}, {0.312439, 0.950569, 0.883918, 0.07296, 0.572631,  0.802194, 0.156748, 0.647973, 0.142384, 0.787631, 0.430859,  0.631801, 0.817772, 0.253225, 0.563215}, {0.744197, 0.149544,  0.412579, 0.0760145,  0.5558}, {{2, 2, 2}, {2, 2, 1}, {0, 0, 1}, {0, 0, 1}, {0, 1,  0}, {0, 0, 1}, {3, 1, 4}, {0, 0, 3}}, 0.955988, 0.270901,  0.728333, 0.505837,  0.643549}, -169.984}, {{{0., 0.320331, 0.844415, 0.432877,  0.0709177, 0.518137, 0., 0.687667, 0.784904, 0.928534, 0.730507,  0.256808, 0., 0.153103, 0.110762, 0.477282, 0.693593, 0.408906,  0., 0.961218, 0.0647035, 0.617579, 0.853106, 0.00523009, 0., 0.,  0.793803, 0.889246, 0.347269, 0.361682, 0.473472, 0., 0.0448305,  0.914391, 0.290764, 0.955334, 0.357163, 0., 0.129487, 0.36223,  0.224827, 0.100355, 0.976384, 0., 0.251468, 0.747545, 0.406762,  0.567478, 0.290251, 0., 0., 0.682842, 0.789183, 0.714372,  0.285021, 0.889039, 0., 0.899938, 0.367104, 0.923339, 0.415567,  0.855107, 0., 0.452713, 0.632575, 0.460232, 0.497944, 0.323225,  0., 0.270345, 0.235405, 0.397589, 0.346841, 0.0188768, 0., 0.,  0.48786, 0.990827, 0.779363, 0.728626, 0.805018, 0., 0.201644,  0.0649908, 0.443605, 0.91598, 0.301706, 0., 0.697887, 0.520266,  0.500413, 0.446599, 0.245174, 0., 0.887691, 0.0401805, 0.948655,  0.921949, 0.617346, 0.}, {0.804775, 0.551067, 0.575108}, {1.,  0.598469, 0.316916, 0.56024, 0.795744, 0.869843, 1., 0.511897,  0.358596, 0.730753, 0.426238, 0.595917, 1., 0.0568903, 0.0328666,  0.905971, 0.0955045, 0.610291, 1., 0.787692, 0.0182807, 0.055324,  0.661636, 0.865743, 1.}, {0.400935, 0.250549, 0.110569, 0.290636,  0.802466, 0.933633, 0.550329, 0.494892, 0.932623, 0.421736,  0.191733, 0.764138, 0.506386, 0.825818, 0.134843}, {0.731272,  0.600414, 0.730314, 0.524551,  0.943579}, {{0, 2, 2}, {2, 0, 2}, {2, 1, 3}, {3, 1, 4}, {1, 1,  1}, {2, 0, 3}, {0, 1, 4}, {3, 1, 2}}, 0.582134, 0.67499,  0.862915, 0.0778359,  0.181199}, -246.406}, {{{0., 0.424441, 0.752346, 0.7872, 0.378732,  0.490808, 0., 0.202016, 0.292309, 0.446109, 0.0690725, 0.0102834,  0., 0.528171, 0.939723, 0.243254, 0.875441, 0.796899, 0.,  0.339308, 0.51294, 0.350889, 0.85332, 0.757175, 0., 0., 0.83795,  0.487974, 0.775484, 0.575976, 0.413509, 0., 0.735628, 0.988284,  0.197244, 0.9227, 0.533612, 0., 0.695975, 0.751135, 0.853628,  0.523328, 0.167804, 0., 0.811413, 0.610374, 0.647888, 0.370905,  0.472104, 0., 0., 0.0974338, 0.296998, 0.517586, 0.714929,  0.259484, 0., 0.809025, 0.742102, 0.138953, 0.845975, 0.0733965,  0., 0.753818, 0.941709, 0.923275, 0.539785, 0.0578433, 0.,  0.190573, 0.0696469, 0.0164568, 0.890039, 0.379161, 0., 0.,  0.459273, 0.368569, 0.519133, 0.907057, 0.361839, 0., 0.0715708,  0.00154773, 0.192128, 0.102356, 0.262546, 0., 0.259446, 0.0531746,  0.256381, 0.18915, 0.505627, 0., 0.111466, 0.333106, 0.649365,  0.447784, 0.920893, 0.}, {0.263459, 0.632908, 0.557745}, {1.,  0.541732, 0.804186, 0.264339, 0.0386118, 0.634675, 1., 0.442347,  0.192768, 0.0370641, 0.442547, 0.339991, 1., 0.930222, 0.777618,  0.389373, 0.0836104, 0.741072, 1., 0.271991, 0.277907, 0.750504,  0.0917073, 0.824207, 1.}, {0.357014, 0.487045, 0.458799, 0.266461,  0.815283, 0.682859, 0.194461, 0.22785, 0.180608, 0.240513,  0.00169245, 0.190785, 0.73806, 0.900522, 0.0714706}, {0.413167,  0.348688, 0.816911, 0.330399,  0.141176}, {{2, 0, 1}, {3, 0, 2}, {0, 0, 0}, {1, 0, 1}, {3, 0,  1}, {0, 2, 2}, {2, 1, 1}, {3, 0, 3}}, 0.0707808, 0.066407,  0.238691, 0.31697,  0.713766}, -3149.77}, {{{0., 0.579362, 0.779892, 0.0505083,  0.898484, 0.896502, 0., 0.585431, 0.822659, 0.717876, 0.65599,  0.583739, 0., 0.631873, 0.979816, 0.755468, 0.512268, 0.218706,  0., 0.631128, 0.938556, 0.18187, 0.0775299, 0.560347, 0., 0.,  0.872149, 0.943179, 0.76056, 0.846581, 0.292788, 0., 0.163287,  0.710052, 0.948097, 0.396286, 0.577855, 0., 0.887393, 0.230221,  0.740296, 0.994116, 0.25552, 0., 0.250405, 0.984828, 0.481848,  0.0368137, 0.619277, 0., 0., 0.0462719, 0.299978, 0.959284,  0.0589304, 0.174122, 0., 0.3568, 0.198724, 0.21235, 0.881335,  0.193513, 0., 0.488672, 0.264253, 0.485049, 0.615658, 0.601278,  0., 0.0340319, 0.744753, 0.621541, 0.345758, 0.783627, 0., 0.,  0.759925, 0.139693, 0.308945, 0.164349, 0.713653, 0., 0.839715,  0.349661, 0.105419, 0.53953, 0.482915, 0., 0.150937, 0.893069,  0.658196, 0.289402, 0.662266, 0., 0.628816, 0.173147, 0.673744,  0.0609874, 0.594784, 0.}, {0.428394, 0.0522024, 0.715229}, {1.,  0.811158, 0.668469, 0.912509, 0.406285, 0.646809, 1., 0.954816,  0.0727945, 0.0566238, 0.54139, 0.415286, 1., 0.58988, 0.905687,  0.648321, 0.757091, 0.300478, 1., 0.243421, 0.019505, 0.583944,  0.626734, 0.182434, 1.}, {0.424721, 0.15555, 0.574532, 0.467204,  0.613563, 0.487081, 0.662022, 0.06092, 0.966755, 0.532265,  0.589228, 0.00429623, 0.425365, 0.116979, 0.999348}, {0.0986096,  0.777044, 0.359888, 0.69887,  0.855189}, {{1, 2, 3}, {3, 1, 0}, {3, 1, 1}, {3, 2, 1}, {1, 0,  0}, {2, 2, 4}, {0, 2, 0}, {3, 2, 0}}, 0.757539, 0.775944,  0.0721362, 0.672755,  0.332818}, -198.578}, {{{0., 0.620394, 0.497605, 0.205551,  0.719255, 0.133312, 0., 0.835582, 0.144631, 0.7525, 0.601047,  0.246354, 0., 0.140334, 0.327135, 0.484068, 0.247006, 0.0417248,  0., 0.550091, 0.12418, 0.548135, 0.186536, 0.792552, 0., 0.,  0.348236, 0.475999, 0.513781, 0.459734, 0.727843, 0., 0.978395,  0.30823, 0.740479, 0.594531, 0.142813, 0., 0.1636, 0.987979,  0.993483, 0.896458, 0.0232653, 0., 0.660844, 0.509415, 0.649453,  0.981541, 0.110753, 0., 0., 0.385235, 0.101317, 0.795004,  0.318202, 0.0369983, 0., 0.625318, 0.281223, 0.858468, 0.309156,  0.646923, 0., 0.972993, 0.117988, 0.714625, 0.504111, 0.809393,  0., 0.130009, 0.721142, 0.607652, 0.786128, 0.469165, 0., 0.,  0.211727, 0.9582, 0.804588, 0.358411, 0.826492, 0., 0.856882,  0.00958324, 0.0402097, 0.789494, 0.231564, 0., 0.72836, 0.181742,  0.480338, 0.584641, 0.755367, 0., 0.0637537, 0.765713, 0.0805305,  0.945973, 0.933745, 0.}, {0.0445715, 0.472878, 0.159845}, {1.,  0.46458, 0.832845, 0.514679, 0.355257, 0.106169, 1., 0.00635315,  0.657796, 0.345674, 0.065959, 0.21686, 1., 0.426232, 0.617314,  0.884217, 0.736522, 0.841591, 1., 0.861948, 0.820463, 0.970809,  0.76106, 0.915975, 1.}, {0.886719, 0.926237, 0.288182, 0.75613,  0.422139, 0.0933921, 0.773503, 0.400872, 0.31597, 0.087039,  0.115707, 0.0551986, 0.250011, 0.870179, 0.689475}, {0.437884,  0.365794, 0.133658, 0.847884,  0.575937}, {{2, 2, 1}, {0, 0, 4}, {3, 1, 1}, {3, 1, 1}, {1, 0,  2}, {3, 0, 4}, {3, 1, 2}, {2, 0, 2}}, 0.545331, 0.162849,  0.0868245, 0.659962,  0.658612}, -150.747}, {{{0., 0.236612, 0.798643, 0.903833,  0.236473, 0.14322, 0., 0.0251397, 0.50296, 0.920503, 0.0561807,  0.909433, 0., 0.447761, 0.670492, 0.186001, 0.219958, 0.00987711,  0., 0.304698, 0.0523437, 0.372074, 0.43394, 0.759367, 0., 0.,  0.889495, 0.285249, 0.773978, 0.100755, 0.652883, 0., 0.486606,  0.870146, 0.864282, 0.509663, 0.461467, 0., 0.367186, 0.943778,  0.453482, 0.552034, 0.919424, 0., 0.273286, 0.267481, 0.332076,  0.909547, 0.968588, 0., 0., 0.215137, 0.960002, 0.475607, 0.20922,  0.325643, 0., 0.674753, 0.701629, 0.108465, 0.67276, 0.188147,  0., 0.831483, 0.244184, 0.163097, 0.72668, 0.464297, 0., 0.300406,  0.709614, 0.174647, 0.544873, 0.0271196, 0., 0., 0.442133,  0.842571, 0.635326, 0.0585319, 0.226996, 0., 0.882569, 0.159719,  0.849311, 0.901353, 0.207816, 0., 0.458091, 0.740846, 0.228594,  0.0196691, 0.626608, 0., 0.496662, 0.0654972, 0.292989, 0.162311,  0.196257, 0.}, {0.355883, 0.118342, 0.617438}, {1., 0.169137,  0.91375, 0.275771, 0.982112, 0.110605, 1., 0.686754, 0.393202,  0.822392, 0.261294, 0.785401, 1., 0.185386, 0.364302, 0.520448,  0.556807, 0.165717, 1., 0.737694, 0.0237856, 0.49131, 0.872728,  0.575383, 1.}, {0.827529, 0.135427, 0.754386, 0.957945, 0.658392,  0.221677, 0.478615, 0.975834, 0.547787, 0.534923, 0.0854126,  0.153441, 0.286493, 0.749522, 0.900026}, {0.78914, 0.766045,  0.192715, 0.734309,  0.0514458}, {{3, 0, 4}, {1, 0, 1}, {3, 1, 3}, {2, 0, 4}, {1, 1,  2}, {0, 1, 0}, {0, 0, 1}, {2, 2, 1}}, 0.742259, 0.701405,  0.861581, 0.476063,  0.914731}, -170.894}, {{{0., 0.565978, 0.107195, 0.518118,  0.256339, 0.344302, 0., 0.62858, 0.542284, 0.708552, 0.809379,  0.543167, 0., 0.388843, 0.422059, 0.0598568, 0.643141, 0.599703,  0., 0.656014, 0.867142, 0.908832, 0.548257, 0.913755, 0., 0.,  0.165737, 0.0472514, 0.0721946, 0.999024, 0.599758, 0., 0.940057,  0.554077, 0.742685, 0.255457, 0.311477, 0., 0.0117932, 0.0341335,  0.446078, 0.76831, 0.62295, 0., 0.612074, 0.386221, 0.125169,  0.0232472, 0.95606, 0., 0., 0.519079, 0.216337, 0.47499,  0.0423057, 0.353343, 0., 0.169085, 0.402795, 0.0432816, 0.753584,  0.229028, 0., 0.848718, 0.300596, 0.498128, 0.917551, 0.836925,  0., 0.266463, 0.0520503, 0.149242, 0.213974, 0.654388, 0., 0.,  0.665829, 0.0240729, 0.190727, 0.698328, 0.14675, 0., 0.807736,  0.715737, 0.656022, 0.793408, 0.638651, 0., 0.312942, 0.612741,  0.0398232, 0.409623, 0.464224, 0., 0.312144, 0.541695, 0.492072,  0.6273, 0.0456817, 0.}, {0.489645, 0.34283, 0.413325}, {1.,  0.391293, 0.823816, 0.318757, 0.222598, 0.692965, 1., 0.677065,  0.511021, 0.506861, 0.0369433, 0.883658, 1., 0.872369, 0.193918,  0.424203, 0.843834, 0.462747, 1., 0.729694, 0.112058, 0.302139,  0.970675, 0.102394, 1.}, {0.0663767, 0.812494, 0.627845, 0.689069,  0.675083, 0.988678, 0.309088, 0.466471, 0.982118, 0.311613,  0.798067, 0.95961, 0.945174, 0.427955, 0.925698}, {0.765692,  0.520972, 0.584121, 0.462952,  0.0359975}, {{1, 0, 2}, {1, 0, 2}, {1, 2, 4}, {2, 2, 3}, {2, 0,  1}, {0, 1, 4}, {1, 0, 1}, {2, 1, 1}}, 0.408913, 0.281982,  0.492277, 0.933603, 0.342537}, -170.581}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      ParameterizedNormalDistribution prior_alpha = 
        parameterized_normal_distribution (data[i].inputs.alphastddev);
      NormalDistribution prior_logbeta = 
        normal_distribution (data[i].inputs.logbetamean, 
                             data[i].inputs.logbetastddev);
      NormalDistribution prior_gamma = 
        normal_distribution (data[i].inputs.gammamean, 
                             data[i].inputs.gammastddev);

      for (unsigned int j = 0; j < 4; ++j)
        {
          for (unsigned int k = 0; k < 5; ++k)
            {
              data[i].inputs.alpha[j * 5 * 5 + k * 5 + k] = drand48 ();
            }
        }

      for (unsigned int k = 0; k < 5; ++k)
        {
          data[i].inputs.gamma[k * 5 + k] = drand48 ();
        }

      double output = qfunc (data[i].inputs.alpha,
                             4,
                             5,
                             data[i].inputs.logbeta,
                             3,
                             data[i].inputs.gamma,
                             data[i].inputs.pz,
                             data[i].inputs.priorz,
                             data[i].inputs.ratings,
                             8,
                             &prior_alpha.base,
                             &prior_logbeta.base,
                             &prior_gamma.base,
                             1);

      assert (fabs (output - data[i].desired_output) <=
              1e-5 * (1 + fabs (output) + fabs (data[i].desired_output)) ||
              (fprintf (stderr, "%g ?= %g\n", output, data[i].desired_output),
               0));
    }
}

typedef struct _DqfuncDalphaTestDatum DqfuncDalphaTestDatum;
struct _DqfuncDalphaTestDatum 
{ 
  struct
    {
      double    alpha[4 * 5 * 5];
      double    logbeta[3];
      double    gamma[5 * 5];
      double    pz[3 * 5];
      double    priorz[5];
      Rating    ratings[8];
      double    alphastddev;
      double    logbetamean;
      double    logbetastddev;
      double    gammamean;
      double    gammastddev;
    }                   inputs;
  double                dalpha[4*5*5];
};

static void
test_dqfuncdalpha (void)
{
  DqfuncDalphaTestDatum data[] = 
    {{{{0, 0.469488, 0.864431, 0.244534, 0.667453, 0.480809, 0, 0.555343,  0.778063, 0.685336, 0.169196, 0.757276, 0, 0.818453, 0.740161,  0.741241, 0.831578, 0.0527617, 0, 0.219189, 0.15712, 0.368626,  0.0167642, 0.810276, 0, 0, 0.875138, 0.87635, 0.0831611, 0.467739,  0.405651, 0, 0.0119182, 0.838627, 0.800286, 0.924842, 0.456575,  0, 0.0605639, 0.11495, 0.755646, 0.699299, 0.242111, 0, 0.374789,  0.014405, 0.867721, 0.189349, 0.155599, 0, 0, 0.857285, 0.499095,  0.172585, 0.345323, 0.982147, 0, 0.622745, 0.0894236, 0.877584,  0.576497, 0.610827, 0, 0.250797, 0.0772983, 0.651655, 0.154252,  0.190233, 0, 0.962348, 0.89601, 0.454953, 0.948122, 0.587559, 0,  0, 0.881605, 0.587232, 0.758773, 0.43196, 0.0243193, 0, 0.0881374,  0.586188, 0.0866364, 0.0421721, 0.465392, 0, 0.496765, 0.209052,  0.465675, 0.854565, 0.245968, 0, 0.131754, 0.81402, 0.700313,  0.0557354, 0.169406, 0}, {0.918011, 0.24536, 0.107613}, {1.,  0.581847, 0.0364061, 0.658128, 0.34884, 0.149887, 1., 0.0120867,  0.56999, 0.762652, 0.0632505, 0.969915, 1., 0.104598, 0.265888,  0.854198, 0.504239, 0.250033, 1., 0.0199197, 0.722444, 0.690219,  0.54972, 0.964184, 1.}, {0.553038, 0.772208, 0.30436, 0.856571,  0.971192, 0.735802, 0.646232, 0.50773, 0.821305, 0.723715,  0.0762414, 0.745078, 0.758054, 0.753801, 0.971643}, {0.47919,  0.903856, 0.249562, 0.72161,  0.459271}, {{0, 2, 2}, {1, 1, 4}, {0, 2, 3}, {3, 0, 2}, {2, 1,  0}, {1, 0, 2}, {0, 1, 4}, {3, 0, 1}}, 0.181412, 0.559343,  0.171891, 0.495086, 0.628374}, {30.7481, 3.61532, -25.1222,  12.7492, -10.4646, -9.57415, 31.2298, -16.8959, -6.81204,  1.90233, -2.58928, 6.77986, 30.3081, -22.2382, -14.735,  3.75771, -9.6537, 5.886, 30.3243, -6.50353, 17.8452, 10.2938,  15.898, 3.90718, 30.262, 31.2794, -8.7468, -26.7425,  18.2229, -4.20344, -7.35136,  31.384, -0.956158, -7.98512, -1.77835, -26.1007, 15.7775, 30.0529,  1.7188, 4.27962, 3.26472, -5.62571, -1.14187, 31.6685, -11.2546,  22.4406, -5.23365, 9.15146, 25.2506, 30.4169,  29.7295, -8.27433, -13.9089, 14.9816, 0.289727, -26.035,  30.6653, -18.4291, 14.8517, -3.40119, -16.1572, 10.9944,  30.5675, -4.31037, 5.89516, 5.24168, 10.8932, 2.06407,  30.7007, -28.5442, -6.08769, 7.34409, -12.0017, 11.6089, 30.7351,  31.9007, -10.3268, -17.774, -2.83161, -2.01203, 4.77865,  29.4755, -3.42376, -0.256329, 21.3652, 1.08406, 14.7217,  30.1164, -11.7742, 2.01905, 12.3027, -12.6022, -1.15963,  31.9816, -2.25077, -2.55856, -2.44103, 14.0742, 25.2755,  32.1061}}, {{{0, 0.787134, 0.867531, 0.638516, 0.657182, 0.0513322,  0, 0.221299, 0.130785, 0.835877, 0.327617, 0.145058, 0, 0.385707,  0.0778226, 0.573816, 0.173415, 0.906517, 0, 0.173967, 0.324254,  0.451804, 0.447246, 0.992555, 0, 0, 0.764912, 0.279914, 0.95216,  0.364181, 0.977777, 0, 0.412383, 0.313644, 0.706999, 0.926445,  0.191083, 0, 0.182859, 0.871122, 0.598828, 0.0460256, 0.797152, 0,  0.7933, 0.0250124, 0.872611, 0.890635, 0.619333, 0, 0, 0.700758,  0.420807, 0.443389, 0.626779, 0.935846, 0, 0.140893, 0.491229,  0.262597, 0.958069, 0.72851, 0, 0.177585, 0.555598, 0.0316239,  0.537427, 0.994726, 0, 0.684476, 0.432796, 0.491401, 0.197574,  0.891176, 0, 0, 0.407783, 0.61879, 0.306939, 0.271843, 0.707025,  0, 0.197984, 0.86355, 0.645064, 0.771179, 0.0570908, 0, 0.372321,  0.382467, 0.81311, 0.328581, 0.194736, 0, 0.826869, 0.781486,  0.791154, 0.20001, 0.142393, 0}, {0.34869, 0.299753,  0.0024357}, {1., 0.251217, 0.940907, 0.680962, 0.695497, 0.979375,  1., 0.233882, 0.482979, 0.831947, 0.33431, 0.462703, 1.,  0.425888, 0.459626, 0.951844, 0.649594, 0.0973075, 1., 0.26489,  0.124975, 0.868108, 0.306154, 0.0648805, 1.}, {0.982582, 0.519417,  0.00640098, 0.0624448, 0.731365, 0.57851, 0.325438, 0.366948,  0.75199, 0.344628, 0.84246, 0.535001, 0.41768, 0.881925,  0.416572}, {0.0753753, 0.465836, 0.232331, 0.319264,  0.810485}, {{0, 0, 3}, {2, 2, 2}, {1, 0, 3}, {1, 0, 0}, {0, 1,  1}, {3, 2, 3}, {3, 1, 1}, {1, 0, 3}}, 0.340861, 0.364224,  0.0131104, 0.745604, 0.358279}, {9.49609, -5.09622,  0.897135, -0.661829, 0.685759, 8.27459, 8.476, 0.334882, 2.55216,  0.062516, 0.139444, 2.34344, 8.73425, 0.412421, 3.4008, 3.40576,  3.34528, -6.86782, 8.8494, 1.04408, -1.39191,  3.38851, -0.942112, -8.89369, 9.11524, 8.67147, -3.92846,  6.66905, -4.74124, 3.72125, -0.526196, 9.39112, -1.09917, 0.488018,  1.36335, -5.10313, 2.34451, 8.61565, 2.08036, -3.53913, 2.98757,  5.27738, -5.99499, 8.51799, -4.51932, 0.839749,  0.266844, -4.73265, -6.40752, 9.6594, 8.86078, -3.74335, 3.79845,  2.20757, 0.726911, 0.432316, 8.75422, 0.391991, 0.019052,  5.01357, -5.31966, -2.22616, 8.31603, 2.24413, -0.752753, 8.17029,  1.11603, -8.51279, 8.86501, -3.48134, -2.57181, 3.3154,  0.615134, -7.06282, 8.72656, 9.06723, -1.8427, 2.99588, 2.69585,  3.98098, 2.48384, 8.48478, 0.560689, -3.69501, 1.75856, -3.65864,  3.23227, 8.86001, 0.204766, 0.824574, 1.41869, 2.14599, -0.371973,  8.31153, -4.61584, -5.54805, 0.298545, 1.11686, -0.867031,  8.86479}}, {{{0, 0.844806, 0.00670939, 0.68316, 0.626915, 0.266296,  0, 0.681271, 0.316212, 0.874925, 0.921668, 0.838811, 0, 0.78121,  0.457245, 0.0397431, 0.42224, 0.705835, 0, 0.991409, 0.807412,  0.102976, 0.89535, 0.650547, 0, 0, 0.443188, 0.0898653, 0.149746,  0.292268, 0.598381, 0, 0.0831559, 0.466586, 0.665353, 0.332085,  0.401885, 0, 0.150374, 0.790429, 0.410417, 0.563074, 0.369164, 0,  0.333184, 0.370674, 0.140834, 0.663329, 0.341775, 0, 0, 0.563263,  0.0378583, 0.767979, 0.691228, 0.120075, 0, 0.947993, 0.618234,  0.39896, 0.521693, 0.864837, 0, 0.151648, 0.733606, 0.189608,  0.462952, 0.00127309, 0, 0.943178, 0.779191, 0.899878, 0.632109,  0.609994, 0, 0, 0.408517, 0.759044, 0.96878, 0.268219, 0.845254,  0, 0.721186, 0.200801, 0.576991, 0.725179, 0.773193, 0, 0.582567,  0.178032, 0.203486, 0.908356, 0.430919, 0, 0.444425, 0.0138781,  0.445404, 0.429646, 0.501248, 0}, {0.234687, 0.545526,  0.797537}, {1., 0.891254, 0.82617, 0.786481, 0.828758, 0.623035,  1., 0.980916, 0.0652952, 0.627957, 0.0460435, 0.255737, 1.,  0.292102, 0.0453903, 0.868012, 0.0522506, 0.383746, 1., 0.614471,  0.423587, 0.0383725, 0.938342, 0.184825, 1.}, {0.922339, 0.803685,  0.392817, 0.387287, 0.0310853, 0.977515, 0.606336, 0.558529,  0.408051, 0.996599, 0.54104, 0.930572, 0.362007, 0.740862,  0.248938}, {0.885182, 0.493995, 0.688611, 0.865192,  0.270711}, {{3, 1, 1}, {3, 0, 1}, {3, 1, 3}, {3, 0, 1}, {2, 2,  1}, {0, 1, 0}, {0, 0, 4}, {3, 1, 3}}, 0.0704086, 0.650239,  0.92685, 0.0858864, 0.14807}, {200.985, 9.63119, 166.243, 21.1761,  39.9133, 71.3875, 202.426,  60.6991, -50.1766, -50.6431, -177.444, -117.446,  202.359, -98.4752, -83.2652, 166.746, -74.428, -64.8377,  202.115, -76.4385, -78.9775, -12.4717, 8.81645, -93.7265, 202.349,  201.72, 90.3838, 148.528, 128.442, 108.221, 4.97316, 201.72,  181.096, -80.9484, -7.54347, -57.7003, -29.481, 201.72,  28.5894, -150.289, 92.3061, -103.043, 2.94154, 201.72, 56.7412,  10.6735, -20.6685, 55.4757, -31.6601, 201.72, 202.181, 65.0933,  159.443, 3.81615, 27.842, 102.077, 200.463, 6.73988, -111.334,  46.527, -95.8416, -123.622, 202.059, 28.5745, -138.76,  137.192, -84.3037, 77.6757, 202.245, -66.2422, -71.6786, -174.294,  61.8482, -85.6867, 202.024, 204.461, 94.793, 14.369, -39.5489,  114.862, -44.3126, 200.527, 53.0129, -28.0471,  11.0537, -136.553, -105.929, 203.136, -59.9652, -25.6945,  134.803, -174.127, -8.98832, 201.355, 34.8179, 84.1766, -83.1757,  103.363, -66.606,  203.287}}, {{{0, 0.846554, 0.534033, 0.698599, 0.116984, 0.869039,  0, 0.927697, 0.14007, 0.708934, 0.87244, 0.386657, 0, 0.209498,  0.346927, 0.131578, 0.137718, 0.324316, 0, 0.852932, 0.442967,  0.272526, 0.0536052, 0.782523, 0, 0, 0.792728, 0.345677, 0.967719,  0.634453, 0.946174, 0, 0.811644, 0.269119, 0.517469, 0.0771357,  0.883947, 0, 0.129049, 0.808535, 0.204696, 0.497291, 0.919551, 0,  0.461609, 0.0731175, 0.359572, 0.595235, 0.608677, 0, 0, 0.630151,  0.0870461, 0.54163, 0.826154, 0.837423, 0, 0.741369, 0.573911,  0.1917, 0.891248, 0.929725, 0, 0.304792, 0.674231, 0.814113,  0.0457783, 0.175742, 0, 0.865696, 0.609417, 0.548488, 0.256191,  0.404087, 0, 0, 0.5363, 0.188915, 0.660956, 0.79541, 0.906149, 0,  0.101869, 0.119326, 0.969256, 0.0687262, 0.3605, 0, 0.545415,  0.777556, 0.177478, 0.430775, 0.240623, 0, 0.103324, 0.363365,  0.384996, 0.0648807, 0.237629, 0}, {0.753948, 0.836509,  0.80869}, {1., 0.833541, 0.217649, 0.647593, 0.147734, 0.0381313,  1., 0.3115, 0.545724, 0.0284078, 0.0688751, 0.242773, 1.,  0.185224, 0.482993, 0.291319, 0.0652956, 0.754449, 1., 0.24237,  0.187995, 0.70193, 0.369453, 0.177489, 1.}, {0.950366, 0.947982,  0.532944, 0.368799, 0.116825, 0.730334, 0.885351, 0.221066,  0.0786936, 0.418834, 0.339627, 0.192658, 0.0098185, 0.176061,  0.154403}, {0.709665, 0.718499, 0.110765, 0.399954,  0.467295}, {{0, 2, 4}, {2, 2, 2}, {0, 0, 2}, {2, 2, 2}, {2, 2,  0}, {2, 2, 2}, {3, 0, 4}, {1, 0, 0}}, 0.530504, 0.408835,  0.0305008, 0.289806, 0.580138}, {4.67733, 0.134717, -2.78901,  0.0677317, 0.220059, -2.78393, 4.64086, -4.05576,  2.24655, -2.61306, -2.78875, -0.324348, 2.84602, 0.186216,  0.664819, 0.849326, 0.0206751, 0.930128,  3.92784, -2.50559, -0.83088, 1.63492, 1.05047, -2.11417, 3.40513,  2.51738, 0.327533, 0.017086, -1.01165, -1.47392, -5.11922,  4.46517, -1.61465, 1.49755, -1.43413, -0.835156, -2.21939, 3.93836,  0.492353, -1.08765, -0.274029, -1.42651, -0.542431,  3.86535, -0.66199, 0.233739, 1.25665, -0.777909, -1.50845, 3.63949,  4.00176, 1.01697, -0.827259, 0.735487, -2.22106, -3.15617,  4.31606, -2.68053, 0.110167, -0.0841572, -2.93811, -2.43538,  3.53154, -0.402432, -0.669729, -2.16459, 0.564637, 1.24048,  4.10212, -2.13621, -1.70356, 0.706283, -0.326994, -0.582415,  4.10501, 4.38823, 1.32326, 0.660968, 0.157447, -4.16723, -2.98139,  4.25906, 1.31329, 2.06281, -5.2679, 0.345876, -0.232555,  3.95288, -1.15445, -2.1028, 0.558589, -1.20869, 1.96047,  3.77791, -0.109388, -0.589171, 1.15857, 1.14625, -0.16933,  3.37843}}, {{{0, 0.460852, 0.497557, 0.921007, 0.463313, 0.730519,  0, 0.612206, 0.699941, 0.384619, 0.311684, 0.272579, 0, 0.507283,  0.374801, 0.135624, 0.118176, 0.797618, 0, 0.656302, 0.0248587,  0.718222, 0.330323, 0.125798, 0, 0, 0.616024, 0.687722, 0.0405172,  0.54566, 0.155172, 0, 0.190165, 0.11951, 0.0823468, 0.424653,  0.577959, 0, 0.419569, 0.697728, 0.112969, 0.30538, 0.912286, 0,  0.322927, 0.977345, 0.187204, 0.114668, 0.666625, 0, 0, 0.952486,  0.468981, 0.784344, 0.540828, 0.336462, 0, 0.78126, 0.743827,  0.995168, 0.181291, 0.591095, 0, 0.624317, 0.912821, 0.756638,  0.013136, 0.204747, 0, 0.215094, 0.643669, 0.707756, 0.292461,  0.892167, 0, 0, 0.666324, 0.520552, 0.177794, 0.225542, 0.713838,  0, 0.0515707, 0.393449, 0.684714, 0.377376, 0.270311, 0, 0.649622,  0.689546, 0.196085, 0.679216, 0.0253058, 0, 0.776725, 0.439448,  0.66608, 0.820559, 0.561632, 0}, {0.795779, 0.958324,  0.528097}, {1., 0.669465, 0.129455, 0.437772, 0.350304, 0.443923,  1., 0.415617, 0.386201, 0.956854, 0.759209, 0.0382407, 1.,  0.11589, 0.307232, 0.069663, 0.842155, 0.436674, 1., 0.281926,  0.292938, 0.402708, 0.770595, 0.461368, 1.}, {0.731306, 0.606929,  0.812271, 0.93327, 0.0618416, 0.477474, 0.374499, 0.582967,  0.617918, 0.0618575, 0.988298, 0.626112, 0.858709, 0.0236167,  0.872408}, {0.31888, 0.789046, 0.181461, 0.435734,  0.036954}, {{3, 0, 4}, {2, 1, 0}, {0, 0, 2}, {0, 2, 1}, {3, 0,  2}, {3, 1, 2}, {0, 2, 0}, {1, 2, 0}}, 0.496109, 0.778754,  0.665139, 0.575586, 0.764802}, {4.44316,  0.0402748, -2.30492, -1.59148, 0.405427, -1.84979,  4.50333, -1.67396, -0.876199, 3.0467, 1.22462, -1.47961,  3.82192, -0.993557, 0.491042, 0.237312, 3.46815, -3.40715,  4.79774, -1.34713, 0.428794, -2.51214, 2.13628, 2.05187, 4.91771,  2.94699, 0.414104, -2.09381, 2.13672, -0.571796, 0.306763, 4.31704,  1.10003, 1.291, 3.77406, 0.169692, -1.98738,  4.61057, -0.965032, -1.41886, -0.205707, 2.18834, -1.92976,  4.07546, -0.159377, -4.16806, 1.22699, 3.06241, -0.678101, 4.54568,  3.52891, -1.09059, -1.17022, -1.31616, -0.600573, -0.309703,  4.61629, -1.41345, -1.37348, -0.114356, 1.27367, -2.09318,  4.77782, -1.92537, -2.39435, -4.33362, 3.84551, 1.23188, 4.55683,  0.553388, -1.57053, -1.22606, 1.98207, -1.74208, 4.14749, 5.68602,  0.358527, -3.97025, 2.12921, -0.153581, -0.835069, 5.42863,  0.368957, 0.518783, 0.0404124, 2.44787, 0.207539,  2.90592, -1.69235, -2.91938, 0.721541, 1.06531, -0.170211,  6.0124, -3.75665, -0.517113, -1.02421, -0.469408, -0.348747,  4.14675}}, {{{0, 0.171825, 0.852868, 0.642316, 0.702961, 0.694351,  0, 0.478369, 0.0593497, 0.0850421, 0.632493, 0.490071, 0,  0.433238, 0.226333, 0.608877, 0.617663, 0.114357, 0, 0.437286,  0.427415, 0.181929, 0.0774033, 0.941178, 0, 0, 0.648662, 0.51679,  0.501817, 0.176376, 0.476837, 0, 0.663921, 0.859501, 0.473415,  0.782486, 0.185552, 0, 0.800151, 0.388373, 0.149992, 0.695481,  0.366913, 0, 0.16204, 0.541116, 0.0778187, 0.252556, 0.724754, 0,  0, 0.1137, 0.89589, 0.175153, 0.783576, 0.465039, 0, 0.3791,  0.673336, 0.6072, 0.988202, 0.715179, 0, 0.813835, 0.133785,  0.205716, 0.529627, 0.0136845, 0, 0.745412, 0.055724, 0.834145,  0.646771, 0.583372, 0, 0, 0.514608, 0.756327, 0.394215, 0.858618,  0.400908, 0, 0.860437, 0.219062, 0.0750423, 0.935869, 0.481337, 0,  0.545727, 0.467842, 0.947667, 0.766158, 0.731891, 0, 0.334057,  0.74195, 0.236531, 0.718207, 0.588644, 0}, {0.686226, 0.402386,  0.0714355}, {1., 0.00527182, 0.171618, 0.646059, 0.67722,  0.146653, 1., 0.77071, 0.785622, 0.458158, 0.0716111, 0.834841,  1., 0.304285, 0.912431, 0.603769, 0.887175, 0.538128, 1., 0.18054,  0.269713, 0.145224, 0.301596, 0.462333, 1.}, {0.681069, 0.458998,  0.899211, 0.390898, 0.675797, 0.28738, 0.253152, 0.713678,  0.529143, 0.516669, 0.467529, 0.25552, 0.457532, 0.681828,  0.163244}, {0.343089, 0.853763, 0.794653, 0.625117,  0.162548}, {{2, 2, 0}, {2, 2, 1}, {3, 0, 0}, {0, 1, 1}, {2, 1,  0}, {0, 2, 1}, {2, 0, 3}, {3, 0, 4}}, 0.58405, 0.649429, 0.32352,  0.700215, 0.902982}, {3.24264, -1.17046, -1.8913, 0.148665,  0.0521528, -1.5356, 2.45255, 0.949738, 2.28994,  1.24927, -1.4398, -0.300039, 3.41529, -0.110294, 2.36616,  0.193123, -0.527726, 1.63592,  3.38839, -0.493381, -0.313632, -0.84513, 0.901319, -1.33148,  3.20404, 2.93156, -1.88614, -1.01189, 0.422855, 1.46826, -0.967954,  2.93156, 0.31306, -0.216581, -0.0447274, -2.08398, 1.90343,  2.93156, -1.45366, 1.53631, 1.33028, 0.561962, 0.501926, 2.93156,  0.0542343, -0.795636, 0.197604, 0.143765, -0.769303, 2.93156,  2.88848, -0.0798657, -1.89996, 0.698798, -0.0483026, -1.26918,  3.33326, 1.5119, -0.353974, -0.183532, -3.93823, 0.326951,  4.40748, -2.87846, 3.46645, 0.279075, 0.720817, 2.37382,  3.00822, -1.35379, 0.462437, -1.98314, -0.723649, -1.37686,  3.79375, 2.79685, -1.05487, -1.44294, 1.29498, -1.66321, -1.39521,  3.5121, -0.157936, 2.03663, 0.71161, -4.07476, 1.64033,  4.5028, -0.176308, 0.137739, -1.67301, 0.514737, -0.396795,  3.66425, -0.849082, -2.47095, 0.430123, -0.953259, -0.0235545,  2.70553}}, {{{0, 0.190431, 0.42431, 0.309317, 0.227185, 0.903051,  0, 0.171158, 0.595639, 0.698042, 0.386382, 0.703628, 0, 0.340119,  0.240509, 0.704554, 0.540384, 0.997031, 0, 0.386746, 0.9099,  0.915268, 0.834482, 0.802696, 0, 0, 0.260472, 0.591748, 0.134267,  0.899714, 0.0700409, 0, 0.167438, 0.82495, 0.672529, 0.16699,  0.99628, 0, 0.229311, 0.974488, 0.780608, 0.292652, 0.889192, 0,  0.733978, 0.0760548, 0.752267, 0.892161, 0.347232, 0, 0, 0.166154,  0.836999, 0.0576788, 0.544536, 0.905683, 0, 0.245252, 0.923412,  0.644822, 0.835642, 0.0778138, 0, 0.0984612, 0.972293, 0.668652,  0.0815337, 0.86915, 0, 0.997805, 0.888044, 0.788882, 0.979958,  0.263827, 0, 0, 0.811989, 0.0366147, 0.0877972, 0.916595,  0.645834, 0, 0.199615, 0.0301184, 0.372059, 0.740152, 0.954363, 0,  0.106707, 0.727237, 0.90451, 0.87655, 0.00824572, 0, 0.754945,  0.235858, 0.795016, 0.139096, 0.757139, 0}, {0.347815, 0.00613389,  0.159137}, {1., 0.493312, 0.535826, 0.969519, 0.0713401,  0.576717, 1., 0.889991, 0.769904, 0.0412217, 0.204658, 0.14984,  1., 0.81554, 0.934515, 0.477421, 0.24533, 0.938991, 1., 0.926269,  0.722476, 0.00947167, 0.143975, 0.787173, 1.}, {0.965337,  0.661657, 0.137841, 0.628036, 0.472025, 0.125831, 0.168322,  0.556696, 0.895307, 0.23584, 0.398418, 0.515474, 0.690649,  0.0860003, 0.582878}, {0.580959, 0.213228, 0.840671, 0.643887,  0.65469}, {{0, 2, 4}, {3, 1, 0}, {0, 0, 1}, {1, 2, 3}, {1, 0,  2}, {3, 2, 2}, {3, 2, 2}, {1, 1, 2}}, 0.490752, 0.831199,  0.499912, 0.867517, 0.525415}, {4.64409, 0.270757, 0.739989,  3.06482, -0.752658, -1.19642, 3.73697, 3.40063,  0.961106, -3.12404, -0.572979, -2.3712, 4.44314, 2.16614,  2.28876, -0.804487, -1.94026, -0.148646, 4.52158,  2.35497, -0.597668, -4.25009, -2.66815, 0.142816, 4.05447, 4.74627,  1.38653, -1.45539, 3.49758, -3.25968, 2.55202, 4.64288,  2.28915, -0.662986, -2.41478, 0.55466, -3.35966, 3.87918,  1.99517, -0.00719578, -0.999888, 0.269116, -1.35572, 4.71625,  1.07224, 3.12488, -2.89449, -3.85269, 1.45726, 4.63716, 4.15217,  1.35842, -1.25052, 3.78612, -1.96479, -1.36592, 4.15217,  2.67707, -0.637392, -2.50625, -2.61995, 0.299064, 4.15217,  2.97744, -0.156862, -0.794025, 0.680109, 0.289992,  4.15217, -0.29703, -0.687466, -3.23625, -3.47115, 2.17303, 4.15217,  4.32004, -1.20765, 1.42082, 3.92718, -3.4072, -0.287824, 4.50672,  1.93947, 3.41416, -1.14275, -2.47884, -3.10114, 3.23576, 3.56639,  1.16987, -2.54102, -2.48388, 3.99992, 4.49205, 0.866797,  2.1393, -3.07422, -0.948676, 0.320521,  4.61902}}, {{{0, 0.169542, 0.362071, 0.239481, 0.0533907,  0.0437104, 0, 0.193749, 0.682785, 0.158083, 0.807871, 0.795331, 0,  0.167311, 0.467434, 0.72187, 0.212453, 0.586351, 0, 0.254206,  0.8812, 0.568566, 0.931661, 0.763453, 0, 0, 0.0500008, 0.0686547,  0.064144, 0.238038, 0.880459, 0, 0.706584, 0.824663, 0.184647,  0.836749, 0.512835, 0, 0.141878, 0.026564, 0.0288781, 0.717505,  0.974568, 0, 0.55913, 0.307008, 0.505052, 0.388216, 0.304924, 0,  0, 0.425808, 0.936485, 0.456555, 0.541471, 0.375807, 0, 0.867831,  0.392411, 0.303433, 0.495348, 0.161247, 0, 0.567748, 0.118785,  0.6586, 0.648411, 0.42587, 0, 0.0922213, 0.629722, 0.930906,  0.451303, 0.533091, 0, 0, 0.322714, 0.425855, 0.0630862, 0.228167,  0.896906, 0, 0.489369, 0.606531, 0.686696, 0.521098, 0.621538, 0,  0.214119, 0.383264, 0.0257499, 0.460292, 0.646371, 0, 0.264478,  0.36715, 0.81188, 0.220501, 0.172257, 0}, {0.737429, 0.880974,  0.769198}, {1., 0.639165, 0.414715, 0.455119, 0.706112, 0.410998,  1., 0.517809, 0.96575, 0.0995813, 0.724302, 0.996711, 1.,  0.344212, 0.885462, 0.341038, 0.970961, 0.88392, 1., 0.239091,  0.0765601, 0.603811, 0.0720399, 0.01859, 1.}, {0.904303, 0.866382,  0.191066, 0.249392, 0.265138, 0.451668, 0.735947, 0.543279,  0.854139, 0.933858, 0.770197, 0.443698, 0.129837, 0.937147,  0.425986}, {0.558236, 0.788799, 0.966186, 0.542065,  0.319145}, {{0, 1, 4}, {3, 0, 3}, {1, 0, 0}, {3, 1, 1}, {1, 1,  3}, {0, 2, 2}, {3, 0, 2}, {3, 1, 0}}, 0.712239, 0.362376,  0.470026, 0.300555, 0.807936}, {2.73754, 1.44813, -1.22007,  0.87115, 0.875843, 1.44221, 2.7663, 0.188064,  0.720834, -1.3408, -0.0626269, 0.502158, 2.38195,  0.81346, -0.258651, -0.452022, 2.45082, -1.02897,  3.52523, -1.22247, -1.34439, 0.570967, -2.39889, -1.15015, 1.61416,  0.788101, 1.79474, 1.28994, 0.294584, 1.34093, -2.50653,  3.63256, -0.0326529, -1.23722, 0.927986, -0.542752, 1.12036,  2.52284, -0.516423, 2.21144, 1.06249, 0.692344, -0.0729852,  0.946566, -0.351729, -0.499659, 0.514428, -0.202701, -2.30668,  3.01858, 1.97128, 0.420588, -1.02856, -0.00283063, 0.324554,  0.069372, 1.97128, -0.689991, 1.13021, -0.401849, 0.451333,  1.64693, 1.97128, -0.440653, 1.51134, -0.626003, 0.635837,  0.902945, 1.97128,  0.289521, -1.09044, -0.644796, -0.747634, -1.01423, 1.97128,  2.65814, 0.405073, -1.21831, 0.427778, 2.01543, -2.23936,  3.90419, -0.522975, -0.155774, -0.365843, -0.512666, -0.256723,  2.91668, 0.671808, 1.53875, 0.160765, -0.477279, 0.320333, 3.15027,  0.863619, -1.98998, -2.36868, 0.33334, 0.464733,  3.95329}}, {{{0, 0.495993, 0.278959, 0.0511637, 0.542798,  0.0443256, 0, 0.543012, 0.507884, 0.688659, 0.110467, 0.772815, 0,  0.0641862, 0.558821, 0.17332, 0.34683, 0.50595, 0, 0.770022,  0.207133, 0.804764, 0.186805, 0.0577834, 0, 0, 0.844758, 0.334738,  0.88625, 0.249848, 0.348764, 0, 0.055779, 0.835086, 0.707049,  0.304439, 0.512767, 0, 0.327202, 0.0183907, 0.193972, 0.739952,  0.263015, 0, 0.459569, 0.0206519, 0.393122, 0.757065, 0.689547, 0,  0, 0.813519, 0.588358, 0.57026, 0.631764, 0.968761, 0, 0.25362,  0.684011, 0.381916, 0.619997, 0.197841, 0, 0.848925, 0.674866,  0.315558, 0.685074, 0.521724, 0, 0.656476, 0.121586, 0.945122,  0.258708, 0.196906, 0, 0, 0.100934, 0.552, 0.501643, 0.507359,  0.287416, 0, 0.963642, 0.931383, 0.875596, 0.318655, 0.710022, 0,  0.247372, 0.49368, 0.698658, 0.512182, 0.398446, 0, 0.818813,  0.3831, 0.827108, 0.876723, 0.162338, 0}, {0.261514, 0.881986,  0.618014}, {1., 0.965431, 0.16058, 0.329986, 0.116371, 0.458072,  1., 0.873164, 0.366344, 0.184989, 0.582476, 0.55451, 1., 0.656321,  0.937617, 0.0887959, 0.855852, 0.144139, 1., 0.539171, 0.269982,  0.472751, 0.317032, 0.662448, 1.}, {0.107645, 0.211237, 0.435046,  0.0444335, 0.142213, 0.0506571, 0.10506, 0.928062, 0.684142,  0.177493, 0.738716, 0.743074, 0.101666, 0.622983,  0.0823952}, {0.805457, 0.0128701, 0.767131, 0.938256,  0.266286}, {{3, 2, 0}, {2, 1, 1}, {2, 2, 2}, {0, 2, 0}, {2, 2,  4}, {0, 0, 1}, {2, 2, 3}, {3, 0, 0}}, 0.742888, 0.29438,  0.621224, 0.603838, 0.635243}, {0.898999, 0.897937, 0.0620041,  0.92231, -0.600613, -0.122133, 2.08575,  0.808896, -0.0324486, -0.749262, 0.847897, -0.890054, 2.0246,  1.2667, 0.781858, -1.00424, 1.08648, -0.489685, 2.23049, -0.315777,  0.027538, -0.759573, 0.304613, 1.17952, 1.90377, 1.81198,  0.218658, -0.315571, -1.00794, -0.241857, 0.198064, 1.81198,  1.48109, -0.849352, -0.945964, 0.503798, 0.0756373, 1.81198,  0.596358, 1.66562, -0.190577, 0.210008, -0.2154, 1.81198, 0.144237,  0.451782, 0.144287, -0.797332, -0.0491032, 1.81198, 3.73542,  0.572756, -1.50616, -1.14441, -1.71475, -0.647022, 3.28521,  0.813414, -1.4789, -0.895906, 0.234836, -0.797833,  2.88348, -0.357785, 0.554675, 0.716738, -0.808976, -1.09748,  2.80599, -0.802466, 0.486732, -1.24596, 0.115626, 0.876297,  1.94148, 0.803757,  1.98477, -0.523631, -0.107856, -0.507355, -0.890935,  2.56539, -0.0253179, -0.877237, -1.08985, -0.126221, -0.196209,  2.04877, 0.906563, 0.920747, -2.17624, 0.822733, -0.214588,  2.32261, -0.392376, -0.477673, -0.609136, -0.983574, 0.997558,  1.92979}}, {{{0, 0.0831425, 0.186178, 0.559405, 0.493029,  0.0324855, 0, 0.0811183, 0.631342, 0.808888, 0.854993, 0.342402,  0, 0.888269, 0.707222, 0.23201, 0.260007, 0.0828124, 0, 0.694352,  0.464879, 0.321751, 0.816526, 0.951464, 0, 0, 0.170499, 0.700527,  0.212688, 0.316221, 0.087357, 0, 0.514348, 0.653284, 0.823192,  0.0548715, 0.43323, 0, 0.0219412, 0.014304, 0.199879, 0.0908281,  0.133672, 0, 0.307082, 0.967869, 0.830822, 0.05086, 0.612731, 0,  0, 0.502989, 0.509071, 0.234334, 0.661266, 0.33249, 0, 0.808544,  0.0216453, 0.345045, 0.245133, 0.294196, 0, 0.368362, 0.521854,  0.190261, 0.860966, 0.34642, 0, 0.50755, 0.990383, 0.770138,  0.212748, 0.200467, 0, 0, 0.0225143, 0.939316, 0.161888, 0.587737,  0.519525, 0, 0.430246, 0.927554, 0.92647, 0.187035, 0.621701, 0,  0.905909, 0.581425, 0.941902, 0.327505, 0.537548, 0, 0.0595716,  0.75164, 0.466539, 0.191127, 0.552022, 0}, {0.761258, 0.696401,  0.978379}, {1., 0.351555, 0.738743, 0.757085, 0.816491, 0.763818,  1., 0.219219, 0.32684, 0.888937, 0.837347, 0.0321837, 1.,  0.705138, 0.983028, 0.255922, 0.0902818, 0.377633, 1., 0.44548,  0.196351, 0.338641, 0.911093, 0.254353, 1.}, {0.644329, 0.577384,  0.214692, 0.275974, 0.292774, 0.83864, 0.457607, 0.459483,  0.528956, 0.619422, 0.130767, 0.570546, 0.691609, 0.587238,  0.425629}, {0.587519, 0.435687, 0.496956, 0.0479965,  0.142039}, {{1, 0, 4}, {0, 0, 4}, {3, 0, 2}, {1, 1, 1}, {1, 2,  0}, {2, 2, 2}, {1, 1, 0}, {3, 1, 3}}, 0.239336, 0.158315,  0.136903, 0.887686, 0.595007}, {17.8944, 5.0514, 9.93965, 3.58288,  4.41938, 13.1266, 17.8428, 2.73468, -5.21618,  0.229461, -0.271387, -5.30579, 17.6862, -3.16288, 4.40555,  0.528237, -2.85864, 5.29933, 17.6396, -4.89438, -4.58139, 0.439496,  1.70106, -12.1323, 17.1188, 17.0749, 2.63193, 1.05009, 10.5605,  8.20545, 10.866, 18.3596, -4.58125, -5.27995, 0.199071,  11.7738, -7.55566, 18.4516, 12.8717, 17.4135, -0.907869, -0.127418,  5.11519, 18.6172, 2.40436, -15.6326, -9.55141, 16.5725, -5.80183,  18.5709, 17.6136, -2.60273, 3.70195, 9.20963, 2.73673, 7.74809,  17.9859, -11.7444, 5.82671, 9.70602, 10.7068, -4.25095, 16.3246,  6.14458, 8.22732, 1.54511, -13.3873, -0.753984,  18.1192, -0.912106, -13.8274, -7.47091, 11.3322, 1.22276, 17.9383,  18.442, 6.68391, -4.73957, 9.41238, 4.28573, 4.62303,  18.5153, -4.48868, -11.252, -0.501675, 11.7418, -10.132,  17.5688, -4.33784, 7.18423, -11.8923, -3.84772, -3.19183, 16.9717,  7.24619, -9.53984, -1.95621, 12.4286, -6.20735, 18.1778}}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      double dalpha[4*5*5];
      double dlogbeta[3];
      double dgamma[5*5];
      ParameterizedNormalDistribution prior_alpha = 
        parameterized_normal_distribution (data[i].inputs.alphastddev);
      NormalDistribution prior_logbeta = 
        normal_distribution (data[i].inputs.logbetamean, 
                             data[i].inputs.logbetastddev);
      NormalDistribution prior_gamma = 
        normal_distribution (data[i].inputs.gammamean, 
                             data[i].inputs.gammastddev);

      memset (dalpha, lrand48 (), 4*5*5 * sizeof (dalpha[0]));

      for (unsigned int j = 0; j < 4; ++j)
        {
          for (unsigned int k = 0; k < 5; ++k)
            {
              data[i].inputs.alpha[j * 5 * 5 + k * 5 + k] = drand48 ();
            }
        }

      for (unsigned int k = 0; k < 5; ++k)
        {
          data[i].inputs.gamma[k * 5 + k] = drand48 ();
        }

      dqfunc (dalpha,
              dlogbeta,
              dgamma,
              data[i].inputs.alpha,
              4,
              5,
              data[i].inputs.logbeta,
              3,
              data[i].inputs.gamma,
              data[i].inputs.pz,
              data[i].inputs.ratings,
              8,
              &prior_alpha.base,
              &prior_logbeta.base,
              &prior_gamma.base,
              0);

      for (unsigned int j = 0; j < 4*5*5; ++j)
        {
          if (j % 5 == (j / 5) % 5)
            {
              assert (dalpha[j] == 0.0 || 
                      (fprintf (stderr, "%u %u: %g ?= 0\n", i, j, dalpha[j]), 
                       0));
            }
          else
            {
              assert (fabs (dalpha[j] - data[i].dalpha[j]) <=
                      5e-5 * (1 + fabs (dalpha[j]) + fabs (data[i].dalpha[j])) ||
                      (fprintf (stderr, "%u %u: %g ?= %g\n", i, j, dalpha[j], data[i].dalpha[j]),
                       0));
            }
        }
    }
}

static void
test_dqfuncdalpha_symmetric (void)
{
  DqfuncDalphaTestDatum data[] = 
    {{{{0, 0.580931, 0.922211, 0.611712, 0.302233, 0.742291, 0, 0.464604,  0.152229, 0.773277, 0.122869, 0.333837, 0, 0.581683, 0.0816682,  0.535631, 0.908208, 0.994165, 0, 0.645981, 0.0386745, 0.860212,  0.852126, 0.406645, 0, 0, 0.880359, 0.723308, 0.96444, 0.811638,  0.299428, 0, 0.801097, 0.352729, 0.509404, 0.557137, 0.336493, 0,  0.200499, 0.736127, 0.434268, 0.00265555, 0.618816, 0, 0.654459,  0.898637, 0.0944475, 0.624652, 0.00847767, 0, 0, 0.859963,  0.234236, 0.772526, 0.601832, 0.979603, 0, 0.510928, 0.808085,  0.790194, 0.680175, 0.70983, 0, 0.455357, 0.28079, 0.123038,  0.373338, 0.254857, 0, 0.544663, 0.68877, 0.370682, 0.636041,  0.890204, 0, 0, 0.790133, 0.276235, 0.0113893, 0.881726, 0.93017,  0, 0.0419986, 0.238864, 0.279894, 0.950566, 0.531071, 0, 0.430779,  0.489699, 0.270391, 0.821241, 0.975422, 0, 0.208909, 0.147353,  0.447903, 0.720565, 0.664246, 0}, {0.458583, 0.077221,  0.0845237}, {1., 0.774043, 0.668451, 0.800986, 0.0731344,  0.892317, 1., 0.738281, 0.758988, 0.834271, 0.612423, 0.787715,  1., 0.227917, 0.403492, 0.122724, 0.517324, 0.406676, 1., 0.42807,  0.913815, 0.36997, 0.958773, 0.707506, 1.}, {0.249569, 0.911387,  0.881552, 0.622982, 0.475526, 0.242936, 0.0805657, 0.549848,  0.583209, 0.504655, 0.321578, 0.715577, 0.970786, 0.71694,  0.093661}, {0.312085, 0.848062, 0.199616, 0.686985,  0.884014}, {{0, 2, 3}, {1, 1, 0}, {3, 1, 2}, {0, 2, 0}, {3, 0,  0}, {0, 2, 1}, {3, 1, 1}, {3, 2, 0}}, 0.934247, 0.829646,  0.728212, 0.176509,  0.684679}, {1.131, -0.144227, -1.17487, -0.169019, -0.323813, -0.144227, 1.05149, 0.543172, 0.996921, 0.369909, -1.17487, 0.543172,  2.07356, -1.00745, 1.66494, -0.169019, 0.996921, -1.00745,  1.05649, -0.216631, -0.323813, 0.369909, 1.66494, -0.216631,  1.23158,  0.983711, -0.280885, -0.58699, -0.902477, -2.11838, -0.280885,  1.17409, -0.0522608, 1.07938, 0.86782, -0.58699, -0.0522608,  1.33516, 0.367535, -0.592888, -0.902477, 1.07938, 0.367535,  1.33467, -0.334059, -2.11838, 0.86782, -0.592888, -0.334059,  1.3313, 1.14571, -0.19688, 0.994973, 0.0652151, -1.21147, -0.19688,  1.14571, 0.520964, -0.112503, 0.100999, 0.994973, 0.520964,  1.14571, -0.521163, 0.281163, 0.0652151, -0.112503, -0.521163,  1.14571, -0.267164, -1.21147, 0.100999, 0.281163, -0.267164,  1.14571, 0.773046, -2.15866, -0.871517,  1.14076, -2.38925, -2.15866, 1.70983, 2.44451, 1.57909,  1.57504, -0.871517, 2.44451, 1.51846, -0.102523, 0.0887676,  1.14076, 1.57909, -0.102523, 1.88651, 1.51998, -2.38925, 1.57504,  0.0887676, 1.51998,  1.73031}}, {{{0, 0.918259, 0.84666, 0.553527, 0.209153, 0.675324,  0, 0.766094, 0.00367939, 0.625944, 0.170669, 0.444516, 0,  0.288103, 0.655158, 0.453729, 0.350855, 0.976018, 0, 0.807096,  0.254113, 0.66387, 0.0920034, 0.872849, 0, 0, 0.424467, 0.935658,  0.915495, 0.18817, 0.506208, 0, 0.0889988, 0.361968, 0.979017,  0.830884, 0.322905, 0, 0.358288, 0.353073, 0.660215, 0.878389,  0.0701857, 0, 0.697916, 0.206486, 0.527534, 0.0941679, 0.89082, 0,  0, 0.952373, 0.863664, 0.00216446, 0.0179713, 0.527906, 0,  0.928005, 0.0866699, 0.829801, 0.0216985, 0.839006, 0, 0.724702,  0.850784, 0.190814, 0.516101, 0.366414, 0, 0.497711, 0.530599,  0.637713, 0.296228, 0.799795, 0, 0, 0.324113, 0.110179, 0.202061,  0.908975, 0.37174, 0, 0.246515, 0.199896, 0.891004, 0.843834,  0.31851, 0, 0.113226, 0.0612025, 0.822136, 0.479504, 0.388524, 0,  0.210418, 0.631321, 0.963403, 0.0221098, 0.712707, 0}, {0.100722,  0.32569, 0.725881}, {1., 0.912912, 0.776609, 0.215511, 0.523821,  0.00393724, 1., 0.404869, 0.968996, 0.323925, 0.112933, 0.561035,  1., 0.650486, 0.210699, 0.051731, 0.738899, 0.170982, 1.,  0.822175, 0.841313, 0.107578, 0.207579, 0.800065, 1.}, {0.128605,  0.00685592, 0.881889, 0.0741836, 0.215693, 0.230247, 0.666378,  0.550363, 0.211756, 0.825378, 0.697382, 0.226438, 0.0988222,  0.264343, 0.0468962}, {0.0157391, 0.0470912, 0.525444, 0.875915,  0.193564}, {{3, 1, 1}, {2, 0, 1}, {0, 0, 0}, {0, 1, 3}, {3, 0,  3}, {2, 2, 4}, {2, 1, 4}, {2, 2, 3}}, 0.205778, 0.417866,  0.668336, 0.393499,  0.0771732}, {23.6332, -0.125646, -4.01816, -16.2365,  15.0998, -0.125646, 23.9214, -16.7207,  45.0811, -13.933, -4.01816, -16.7207, 24.2165,  16.8479, -20.5285, -16.2365, 45.0811, 16.8479, 23.4295, -0.234487,  15.0998, -13.933, -20.5285, -0.234487, 24.0848, 23.6157,  23.0699, -7.5121, -33.0612, 15.8532, 23.0699, 23.6157, 14.919,  28.6707, -30.9409, -7.5121, 14.919, 23.6157,  13.8009, -6.72452, -33.0612, 28.6707, 13.8009, 23.6157, 5.86891,  15.8532, -30.9409, -6.72452, 5.86891, 23.6157,  24.6264, -1.69781, -3.63399, 10.0593, 23.6067, -1.69781,  24.3529, -25.2662, 42.1193, -25.1837, -3.63399, -25.2662,  24.5704, -3.25308, -30.7521, 10.0593, 42.1193, -3.25308, 23.4886,  14.8061, 23.6067, -25.1837, -30.7521, 14.8061, 22.8879, 23.7438,  27.7498, 31.9315, 0.660733, -18.0265, 27.7498, 22.9664, 7.20275,  36.3017, -27.7188, 31.9315, 7.20275, 24.0097, 24.8208, 7.81474,  0.660733, 36.3017, 24.8208, 23.6241, 29.0421, -18.0265, -27.7188,  7.81474, 29.0421,  24.0372}}, {{{0, 0.41101, 0.786447, 0.319315, 0.86148, 0.180763, 0,  0.120069, 0.768953, 0.649725, 0.355385, 0.422687, 0, 0.542515,  0.550903, 0.0910416, 0.375791, 0.526776, 0, 0.503811, 0.565597,  0.499877, 0.333212, 0.298033, 0, 0, 0.147731, 0.831541, 0.939713,  0.22086, 0.736721, 0, 0.0450941, 0.620397, 0.359379, 0.555958,  0.925025, 0, 0.851444, 0.709655, 0.200572, 0.502338, 0.308929, 0,  0.158752, 0.109531, 0.126547, 0.782154, 0.65494, 0, 0, 0.543933,  0.62667, 0.448942, 0.356907, 0.396202, 0, 0.795129, 0.509229,  0.136048, 0.659481, 0.750035, 0, 0.888832, 0.776668, 0.103524,  0.82501, 0.037388, 0, 0.0670137, 0.902951, 0.322672, 0.728459,  0.908262, 0, 0, 0.79342, 0.196126, 0.946305, 0.253321, 0.249487,  0, 0.569456, 0.497363, 0.896414, 0.853285, 0.774326, 0, 0.988134,  0.760366, 0.193803, 0.0242913, 0.0993016, 0, 0.983698, 0.0902797,  0.199281, 0.0619136, 0.916684, 0}, {0.187328, 0.876609,  0.333455}, {1., 0.00842255, 0.393908, 0.680483, 0.38715, 0.755101,  1., 0.144421, 0.111028, 0.889787, 0.858687, 0.291136, 1.,  0.336701, 0.901653, 0.0983205, 0.0973328, 0.31241, 1., 0.802351,  0.114622, 0.00705305, 0.113129, 0.740437, 1.}, {0.197938,  0.819725, 0.23652, 0.406982, 0.189515, 0.425817, 0.556037,  0.0198325, 0.434414, 0.281396, 0.445009, 0.130046, 0.575727,  0.990259, 0.108308}, {0.228393, 0.477407, 0.892927, 0.795898,  0.426042}, {{2, 2, 0}, {1, 2, 4}, {3, 0, 3}, {2, 1, 3}, {1, 2,  1}, {2, 0, 0}, {1, 2, 3}, {2, 2, 0}}, 0.362784, 0.885874,  0.682769, 0.685605, 0.164847}, {7.59806, -6.11777, -5.96507,  5.48835, -7.20798, -6.11777, 7.59806, 0.370056, -9.99791,  3.648, -5.96507, 0.370056, 7.59806, -3.12757, 5.33003,  5.48835, -9.99791, -3.12757, 7.59806, 4.53665, -7.20798, 3.648,  5.33003, 4.53665, 7.59806, 8.1932, -2.13658, -6.20597, -4.0006,  2.43793, -2.13658, 7.56065, 1.61413, -8.61967, 7.89289, -6.20597,  1.61413, 8.42131, -7.92296, 2.46771, -4.0006, -8.61967, -7.92296,  7.69891, 9.53857, 2.43793, 7.89289, 2.46771, 9.53857, 7.57599,  7.05494, -8.77715, -4.78248, 0.335414, 0.598407, -8.77715,  8.56376, -9.38379, -6.38856, 12.4744, -4.78248, -9.38379,  8.4143, -7.85611, 2.2604, 0.335414, -6.38856, -7.85611, 7.95707,  12.0662, 0.598407, 12.4744, 2.2604, 12.0662, 7.95463,  7.67197, -11.7637, 3.13902, -4.19128, 2.14869, -11.7637,  7.95426, -6.23173, -6.55513, 0.0480002, 3.13902, -6.23173,  7.69327, -10.0954, 2.21792, -4.19128, -6.55513, -10.0954,  7.30536, -2.89874, 2.14869, 0.0480002, 2.21792, -2.89874,  7.68024}}, {{{0, 0.066149, 0.446249, 0.278623, 0.975331, 0.640332,  0, 0.890213, 0.25879, 0.540917, 0.358937, 0.445204, 0, 0.128744,  0.96519, 0.368677, 0.336896, 0.900351, 0, 0.487783, 0.475751,  0.540999, 0.474309, 0.124998, 0, 0, 0.589877, 0.858229, 0.788704,  0.960152, 0.523728, 0, 0.41198, 0.510081, 0.984821, 0.883396,  0.521767, 0, 0.251291, 0.443904, 0.524459, 0.0765634, 0.122547, 0,  0.478714, 0.155782, 0.739667, 0.222196, 0.990931, 0, 0, 0.680031,  0.198669, 0.747887, 0.865933, 0.0901537, 0, 0.340439, 0.959184,  0.905781, 0.566425, 0.928459, 0, 0.449103, 0.920961, 0.68303,  0.406692, 0.197812, 0, 0.477057, 0.15857, 0.330128, 0.0752655,  0.998343, 0, 0, 0.0027887, 0.590461, 0.85307, 0.00741148,  0.322758, 0, 0.391793, 0.105183, 0.141479, 0.232604, 0.0513536, 0,  0.145999, 0.235697, 0.666179, 0.122895, 0.696896, 0, 0.314737,  0.983149, 0.716203, 0.499084, 0.83768, 0}, {0.824579, 0.386074,  0.423818}, {1., 0.839337, 0.82179, 0.795613, 0.570749, 0.831925,  1., 0.499032, 0.403821, 0.465566, 0.690447, 0.266428, 1.,  0.352467, 0.319567, 0.45475, 0.600249, 0.229572, 1., 0.622671,  0.140013, 0.6171, 0.51337, 0.123587, 1.}, {0.302333, 0.792521,  0.127295, 0.699769, 0.462996, 0.970731, 0.331682, 0.12902,  0.631071, 0.471699, 0.927861, 0.663454, 0.940624, 0.205271,  0.575394}, {0.343887, 0.485874, 0.605021, 0.345822,  0.721216}, {{1, 1, 3}, {3, 0, 0}, {2, 0, 1}, {3, 0, 0}, {3, 0,  1}, {2, 0, 1}, {3, 1, 4}, {2, 1, 0}}, 0.345861, 0.987921,  0.832452, 0.597629, 0.0435278}, {8.35982, 12.9274, 6.27891,  8.64389, -6.76447, 12.9274, 8.35982, -6.5404, 2.42486, -1.25984,  6.27891, -6.5404, 8.35982, 3.74057, -10.7946, 8.64389, 2.42486,  3.74057, 8.35982, 2.25528, -6.76447, -1.25984, -10.7946, 2.25528,  8.35982, 8.99183, 4.5129, -0.412776, -1.01662, -6.289, 4.5129,  8.54242, 1.58915, -2.03084, -8.57351, -0.412776, 1.58915, 8.42226,  1.76088, -1.90151, -1.01662, -2.03084, 1.76088, 7.74389,  2.0051, -6.289, -8.57351, -1.90151, 2.0051, 8.63815, 8.09159,  1.59728, 11.2125, 0.570094, -5.14015, 1.59728, 6.8331,  3.20087, -11.9501, -8.94593, 11.2125, 3.20087,  8.64585, -0.742214, -9.78405, 0.570094, -11.9501, -0.742214,  10.3229, 3.71508, -5.14015, -8.94593, -9.78405, 3.71508, 9.88657,  7.97978, 12.1674, 3.70766, -3.66283, 7.85338, 12.1674, 8.05324,  2.28499, 6.0102, 5.71511, 3.70766, 2.28499, 8.70739, 5.0105,  2.03043, -3.66283, 6.0102, 5.0105, 10.1471, 5.64313, 7.85338,  5.71511, 2.03043, 5.64313,  8.67186}}, {{{0, 0.1954, 0.705157, 0.89786, 0.580532, 0.224668, 0,  0.373475, 0.76884, 0.949461, 0.752969, 0.445614, 0, 0.105386,  0.00883712, 0.547699, 0.870219, 0.761499, 0, 0.522963, 0.942677,  0.524397, 0.0402837, 0.177102, 0, 0, 0.954756, 0.691945, 0.442655,  0.133574, 0.759356, 0, 0.986788, 0.544795, 0.553043, 0.534688,  0.613313, 0, 0.775955, 0.603582, 0.781718, 0.167699, 0.670569, 0,  0.594745, 0.23402, 0.297479, 0.90907, 0.0717816, 0, 0, 0.291343,  0.773082, 0.868786, 0.89468, 0.336587, 0, 0.0811369, 0.426131,  0.761105, 0.57723, 0.094349, 0, 0.881336, 0.208063, 0.0425423,  0.481036, 0.105381, 0, 0.604481, 0.260824, 0.313337, 0.434812,  0.00973619, 0, 0, 0.026804, 0.0158581, 0.525742, 0.937955,  0.735461, 0, 0.242776, 0.656956, 0.0432751, 0.398875, 0.161639, 0,  0.230825, 0.28217, 0.821645, 0.0672902, 0.349489, 0, 0.0741071,  0.779102, 0.586254, 0.244108, 0.469626, 0}, {0.518278, 0.272916,  0.809297}, {1., 0.45989, 0.491474, 0.257058, 0.283555, 0.521935,  1., 0.756013, 0.0142823, 0.626599, 0.47866, 0.357138, 1.,  0.852643, 0.395774, 0.196491, 0.535494, 0.785353, 1., 0.0462846,  0.122383, 0.756391, 0.199099, 0.802176, 1.}, {0.652757, 0.238113,  0.926183, 0.99288, 0.192867, 0.746639, 0.669124, 0.709325,  0.670932, 0.990626, 0.654842, 0.0827263, 0.192271, 0.633487,  0.802199}, {0.686953, 0.995781, 0.0979937, 0.016846,  0.640668}, {{3, 1, 2}, {2, 2, 3}, {1, 1, 4}, {2, 1, 4}, {2, 0,  0}, {2, 1, 1}, {3, 1, 1}, {0, 1, 2}}, 0.873397, 0.341602,  0.817747, 0.838492, 0.22064}, {1.64419,  1.17517, -1.31379, -1.48866, -0.436137, 1.17517, 1.60036,  0.448588, -1.76751, -0.64815, -1.31379, 0.448588, 0.619984,  1.53956, 0.347619, -1.48866, -1.76751, 1.53956,  1.60037, -0.90242, -0.436137, -0.64815, 0.347619, -0.90242,  1.71197, 1.62876, -1.10772, -0.246739, -0.137016,  0.0167601, -1.10772,  1.65823, -0.40769, -1.07083, -0.323626, -0.246739, -0.40769,  1.68523, 0.447061, -1.12521, -0.137016, -1.07083, 0.447061,  1.61843, -1.99438, 0.0167601, -0.323626, -1.12521, -1.99438,  0.412021, 2.16314, 0.685645, -1.40073, -3.8079, -2.06023, 0.685645,  1.11789, 2.51959, -0.7611, -1.78887, -1.40073, 2.51959, 2.53048,  0.279835, 1.72695, -3.8079, -0.7611, 0.279835,  2.01336, -2.73154, -2.06023, -1.78887, 1.72695, -2.73154, 1.85593,  1.83581, 1.07947, 1.22159, -0.193761, -1.36466, 1.07947, 0.864999,  0.177156, -2.17533, 1.27855, 1.22159, 0.177156, 0.829763,  1.44645, -0.223865, -0.193761, -2.17533, 1.44645, 1.80492,  0.991176, -1.36466, 1.27855, -0.223865, 0.991176,  1.98986}}, {{{0, 0.10349, 0.891564, 0.845612, 0.0277728, 0.356851,  0, 0.22244, 0.136287, 0.356841, 0.366225, 0.567598, 0, 0.0535609,  0.16457, 0.732738, 0.765399, 0.366608, 0, 0.168789, 0.634744,  0.748553, 0.72594, 0.295392, 0, 0, 0.293142, 0.930806, 0.887449,  0.0747522, 0.189653, 0, 0.039242, 0.0418365, 0.0469795, 0.832802,  0.816802, 0, 0.905549, 0.690138, 0.466576, 0.249204, 0.851988, 0,  0.525568, 0.733838, 0.483805, 0.48538, 0.356779, 0, 0, 0.0990934,  0.735251, 0.75944, 0.0613871, 0.805951, 0, 0.804445, 0.871991,  0.986635, 0.616299, 0.765203, 0, 0.830155, 0.939655, 0.783497,  0.948401, 0.924605, 0, 0.249517, 0.316921, 0.699197, 0.0726169,  0.723949, 0, 0, 0.583083, 0.215393, 0.587237, 0.367169, 0.48399,  0, 0.480141, 0.827797, 0.305782, 0.678039, 0.675696, 0, 0.955806,  0.319147, 0.0617397, 0.910493, 0.125651, 0, 0.379492, 0.278242,  0.962092, 0.201046, 0.129975, 0}, {0.961321, 0.262895,  0.128429}, {1., 0.406026, 0.378238, 0.0475022, 0.541193, 0.038857,  1., 0.894248, 0.567361, 0.713395, 0.733075, 0.216209, 1.,  0.891664, 0.757589, 0.413927, 0.154469, 0.981171, 1., 0.631938,  0.0344353, 0.876227, 0.0190785, 0.430892, 1.}, {0.90446, 0.914906,  0.756184, 0.302463, 0.498434, 0.536668, 0.708681, 0.76127,  0.459577, 0.64242, 0.141321, 0.0478747, 0.726502, 0.426211,  0.249656}, {0.290285, 0.312575, 0.271742, 0.268485,  0.658347}, {{2, 2, 1}, {1, 2, 4}, {0, 0, 2}, {1, 1, 4}, {3, 2,  0}, {2, 0, 4}, {1, 1, 0}, {3, 2, 4}}, 0.27814, 0.395515,  0.249407, 0.227455, 0.373679}, {13.742,  8.97812, -15.4964, -20.5178, 14.367, 8.97812, 13.6268, 15.715,  11.8016, 9.63513, -15.4964, 15.715, 11.5715, 21.6245,  14.6669, -20.5178, 11.8016, 21.6245, 13.1644, 12.3585, 14.367,  9.63513, 14.6669, 12.3585, 13.2867, 12.7121,  2.61565, -14.8379, -21.9803, 11.2744, 2.61565, 13.346, 23.3914,  14.4952, 17.1348, -14.8379, 23.3914, 13.8595, 0.114852,  0.53534, -21.9803, 14.4952, 0.114852, 13.4653, 2.21113, 11.2744,  17.1348, 0.53534, 2.21113, 12.3245, 13.7836,  9.34878, -8.75539, -18.1478, 11.2897, 9.34878, 14.045,  1.93705, -8.13085, -9.58048, -8.75539, 1.93705, 14.5953,  1.98146, -6.38529, -18.1478, -8.13085, 1.98146, 13.5134, 9.77128,  11.2897, -9.58048, -6.38529, 9.77128, 12.2219, 12.8582, -4.5665,  3.83732, -14.2186, 4.21621, -4.5665, 12.9604, 11.0074, -6.58879,  10.6156, 3.83732, 11.0074, 13.4129, -1.38096,  10.9538, -14.2186, -6.58879, -1.38096, 13.2617, 6.35901, 4.21621,  10.6156, 10.9538, 6.35901,  12.7954}}, {{{0, 0.480609, 0.493223, 0.924993, 0.875245, 0.943941,  0, 0.784542, 0.163722, 0.415668, 0.30152, 0.643221, 0, 0.115848,  0.689166, 0.875309, 0.393565, 0.825562, 0, 0.376591, 0.603568,  0.12508, 0.167215, 0.0984509, 0, 0, 0.208053, 0.875673, 0.93976,  0.724772, 0.727444, 0, 0.38245, 0.0147675, 0.849526, 0.783503,  0.597908, 0, 0.851045, 0.433858, 0.481983, 0.954686, 0.735197, 0,  0.744693, 0.606673, 0.561121, 0.909635, 0.368102, 0, 0,  0.00310577, 0.436041, 0.74242, 0.269651, 0.795053, 0, 0.560368,  0.80266, 0.544879, 0.067609, 0.177918, 0, 0.787892, 0.695353,  0.284106, 0.580011, 0.936847, 0, 0.261495, 0.802123, 0.625324,  0.20165, 0.516802, 0, 0, 0.19545, 0.0642034, 0.292015, 0.1487,  0.192344, 0, 0.628162, 0.549595, 0.879049, 0.397291, 0.0677941, 0,  0.746936, 0.334169, 0.329682, 0.889876, 0.959044, 0, 0.638816,  0.0455763, 0.309865, 0.0221966, 0.377322, 0}, {0.243453, 0.68454,  0.820547}, {1., 0.86052, 0.048003, 0.620337, 0.528532, 0.71182,  1., 0.855659, 0.992175, 0.978937, 0.832772, 0.458368, 1.,  0.924381, 0.232001, 0.498602, 0.128685, 0.0345051, 1., 0.272957,  0.859786, 0.0831092, 0.72464, 0.250761, 1.}, {0.482464, 0.839656,  0.0400997, 0.430214, 0.621944, 0.791653, 0.419763, 0.901682,  0.910124, 0.935994, 0.427588, 0.922745, 0.0773528, 0.477627,  0.503207}, {0.690744, 0.57875, 0.348941, 0.468702,  0.417787}, {{3, 1, 4}, {0, 2, 3}, {0, 0, 3}, {0, 0, 4}, {3, 1,  4}, {3, 1, 3}, {1, 2, 4}, {3, 2, 0}}, 0.718964, 0.265832,  0.744062, 0.167026, 0.2365}, {2.89455,  2.50882, -1.27521, -2.4263, -1.49034, 2.50882, 3.39371, 0.673497,  1.61937, 2.32738, -1.27521, 0.673497, 2.03785,  3.52436, -1.45785, -2.4263, 1.61937, 3.52436,  0.966657, -1.98654, -1.49034, 2.32738, -1.45785, -1.98654, 2.20842,  2.40358, 3.23102, -3.12663, -1.12728, -1.52402, 3.23102, 2.599,  2.14514, 4.85887, -1.41153, -3.12663, 2.14514, 2.0193,  0.361022, -0.700016, -1.12728, 4.85887, 0.361022,  2.38403, -2.71637, -1.52402, -1.41153, -0.700016, -2.71637,  1.39457, 1.93457, 3.31746, -1.50138, -0.472357, 1.00165, 3.31746,  1.93457, 1.14252, 0.733261, 1.67943, -1.50138, 1.14252, 1.93457,  0.528095, -1.79278, -0.472357, 0.733261, 0.528095, 1.93457,  0.0443496, 1.00165, 1.67943, -1.79278, 0.0443496, 1.93457, 2.44199,  2.73856, 2.73676, 0.945496, 0.125642, 2.73856, 3.85209, 1.93413,  2.37703, -0.558907, 2.73676, 1.93413,  3.84083, -0.0694047, -1.72531, 0.945496, 2.37703, -0.0694047,  2.86906, -5.44983, 0.125642, -0.558907, -1.72531, -5.44983,  0.720062}}, {{{0, 0.426176, 0.703962, 0.736812, 0.614556, 0.634523,  0, 0.2842, 0.83513, 0.704431, 0.698528, 0.856612, 0, 0.912385,  0.627079, 0.220902, 0.353404, 0.221641, 0, 0.0483281, 0.87196,  0.884702, 0.803854, 0.329364, 0, 0, 0.606128, 0.14064, 0.636827,  0.0928636, 0.179953, 0, 0.436678, 0.900015, 0.478308, 0.54543,  0.152479, 0, 0.064885, 0.773877, 0.846902, 0.295867, 0.1525, 0,  0.146798, 0.626, 0.942463, 0.93086, 0.0984699, 0, 0, 0.75404,  0.0577603, 0.127006, 0.769106, 0.147912, 0, 0.91712, 0.490179,  0.676243, 0.967959, 0.480442, 0, 0.590164, 0.197935, 0.422529,  0.327963, 0.525279, 0, 0.424058, 0.575627, 0.0320965, 0.372778,  0.27726, 0, 0, 0.949627, 0.0896339, 0.441919, 0.17879, 0.195587,  0, 0.0318736, 0.314913, 0.409684, 0.0476758, 0.114754, 0,  0.824734, 0.733441, 0.0797168, 0.634312, 0.234571, 0, 0.535507,  0.657188, 0.306348, 0.709292, 0.111448, 0}, {0.0815602, 0.274252,  0.336514}, {1., 0.834188, 0.131933, 0.184618, 0.894595, 0.655398,  1., 0.936346, 0.152744, 0.579682, 0.245714, 0.88867, 1.,  0.0379907, 0.754948, 0.512273, 0.808953, 0.403679, 1., 0.520377,  0.976767, 0.151765, 0.097331, 0.811085, 1.}, {0.865318, 0.0702051,  0.823079, 0.474571, 0.0311298, 0.938272, 0.638462, 0.579977,  0.375732, 0.00192667, 0.485717, 0.000294897, 0.130017, 0.113257,  0.447727}, {0.245347, 0.617744, 0.304304, 0.0440474,  0.72497}, {{0, 2, 3}, {0, 0, 0}, {2, 2, 0}, {0, 0, 0}, {0, 2,  0}, {3, 1, 1}, {3, 0, 1}, {2, 0, 3}}, 0.640978, 0.152539,  0.946716, 0.913885, 0.77566}, {0.993246, 2.5269, -3.95899, -3.916,  1.37543, 2.5269, 2.48135, 3.72488, -3.13779, -0.427447, -3.95899,  3.72488, 3.14701, -4.03463, 1.14708, -3.916, -3.13779, -4.03463,  2.70992, 2.47288, 1.37543, -0.427447, 1.14708, 2.47288, 2.85211,  2.43396, 1.11018, -0.0423853, -2.20132, 3.90277, 1.11018, 2.43396,  2.43234, -3.63766, 0.49348, -0.0423853, 2.43234,  2.43396, -0.130919, -0.0921468, -2.20132, -3.63766, -0.130919,  2.43396, 1.81855, 3.90277, 0.49348, -0.0921468, 1.81855, 2.43396,  2.20587, 0.582495, 0.879887, -0.266068, 0.236439, 0.582495,  2.46059, 0.208896, -1.59555, -0.372416, 0.879887, 0.208896,  2.73273, -3.3324, 3.11438, -0.266068, -1.59555, -3.3324, 2.10902,  0.671526, 0.236439, -0.372416, 3.11438, 0.671526, 2.65031,  3.03739, -2.46795, 1.15409, -0.712719, 3.97848, -2.46795, 1.77927,  3.43393, -1.40688, 0.951604, 1.15409, 3.43393, 2.88709, -3.54123,  0.298825, -0.712719, -1.40688, -3.54123, 2.75205, 0.0995628,  3.97848, 0.951604, 0.298825, 0.0995628,  2.44446}}, {{{0, 0.0823335, 0.123637, 0.439314, 0.74453, 0.144061,  0, 0.485175, 0.859337, 0.368798, 0.142135, 0.999458, 0, 0.859042,  0.238781, 0.0288777, 0.551732, 0.613695, 0, 0.621036, 0.724574,  0.507684, 0.888725, 0.980059, 0, 0, 0.572035, 0.560968, 0.974839,  0.204399, 0.489702, 0, 0.437331, 0.535526, 0.459869, 0.34564,  0.952155, 0, 0.676188, 0.0910706, 0.203506, 0.952697, 0.817146, 0,  0.85229, 0.174628, 0.400966, 0.203451, 0.231253, 0, 0, 0.450054,  0.893282, 0.314726, 0.251195, 0.878019, 0, 0.332314, 0.339886,  0.0467959, 0.388318, 0.894983, 0, 0.804361, 0.586927, 0.0426775,  0.942828, 0.128173, 0, 0.495856, 0.839172, 0.990131, 0.311027,  0.643567, 0, 0, 0.664544, 0.589165, 0.107576, 0.412313, 0.21449,  0, 0.695883, 0.79285, 0.161119, 0.336471, 0.36357, 0, 0.452964,  0.114323, 0.948153, 0.468587, 0.648603, 0, 0.527396, 0.905475,  0.525759, 0.52043, 0.0315392, 0}, {0.0663036, 0.535628,  0.209403}, {1., 0.387972, 0.40176, 0.946463, 0.101827, 0.975659,  1., 0.18727, 0.25058, 0.308977, 0.814541, 0.850799, 1., 0.88701,  0.856013, 0.700218, 0.902646, 0.418423, 1., 0.20741, 0.172822,  0.997171, 0.892664, 0.68698, 1.}, {0.141283, 0.930867, 0.357036,  0.477577, 0.753311, 0.529108, 0.410573, 0.375749, 0.777652,  0.341838, 0.159993, 0.0667723, 0.963111, 0.491039,  0.272983}, {0.210759, 0.262893, 0.588392, 0.854559,  0.00334852}, {{2, 1, 0}, {3, 1, 1}, {3, 0, 1}, {2, 1, 0}, {1, 1,  0}, {0, 1, 0}, {3, 2, 0}, {2, 0, 1}}, 0.0900708, 0.591221,  0.961895, 0.316368, 0.948788}, {122.622, 75.0739, 68.3011,  124.096, -158.895, 75.0739, 123.491, -73.2522, -149.887, -14.5155,  68.3011, -73.2522, 123.467, 7.0763, 152.437, 124.096, -149.887,  7.0763, 123.846, -101.696, -158.895, -14.5155, 152.437, -101.696,  123.47, 122.699, -45.8519, -39.679, -8.14204, -25.5036, -45.8519,  123.522, -61.4233, -69.8938, -36.9987, -39.679, -61.4233, 123.475,  52.2356, 188.913, -8.14204, -69.8938, 52.2356,  123.884, -158.793, -25.5036, -36.9987, 188.913, -158.793, 123.442,  122.118, -16.2042, -122.141, 154.131, -37.1682, -16.2042,  122.918, -35.3458, -21.4987, 64.9561, -122.141, -35.3458, 123.922,  20.8644, 66.8387, 154.131, -21.4987, 20.8644,  124.352, -70.3462, -37.1682, 64.9561, 66.8387, -70.3462, 123.819,  123.466, -68.9283, -46.9185, 207.202, -76.4012, -68.9283,  122.166, -125.903, -135.066, 35.9158, -46.9185, -125.903, 123.943,  107.774, 183.824, 207.202, -135.066, 107.774,  124.039, -78.2944, -76.4012, 35.9158, 183.824, -78.2944,  123.723}}, {{{0, 0.660354, 0.604859, 0.838792, 0.195477, 0.131246,  0, 0.194286, 0.463042, 0.417826, 0.789408, 0.034293, 0, 0.39627,  0.454715, 0.298369, 0.76131, 0.185511, 0, 0.191821, 0.709977,  0.906751, 0.182162, 0.101751, 0, 0, 0.118756, 0.944856, 0.865794,  0.152963, 0.458402, 0, 0.339997, 0.0270025, 0.957486, 0.327156,  0.145711, 0, 0.56396, 0.53966, 0.537748, 0.111418, 0.16769, 0,  0.0849459, 0.239379, 0.350108, 0.98218, 0.893124, 0, 0, 0.529401,  0.443357, 0.800017, 0.791374, 0.410646, 0, 0.498501, 0.934223,  0.638411, 0.952244, 0.158505, 0, 0.907221, 0.680925, 0.625088,  0.0127939, 0.34326, 0, 0.141264, 0.0873398, 0.901376, 0.17557,  0.0563185, 0, 0, 0.847961, 0.551268, 0.19339, 0.163194, 0.31856,  0, 0.107911, 0.393373, 0.37182, 0.907914, 0.60941, 0, 0.45915,  0.733409, 0.955671, 0.450905, 0.551929, 0, 0.0524846, 0.330583,  0.438111, 0.208669, 0.91122, 0}, {0.243243, 0.536735,  0.0330989}, {1., 0.854902, 0.395282, 0.985467, 0.839709, 0.691708,  1., 0.076722, 0.877556, 0.446336, 0.319887, 0.168808, 1.,  0.268146, 0.987186, 0.586478, 0.213137, 0.817241, 1., 0.435257,  0.533993, 0.882554, 0.379129, 0.226588, 1.}, {0.622773, 0.639311,  0.842394, 0.193489, 0.767871, 0.244029, 0.856927, 0.35378,  0.0761637, 0.167307, 0.979372, 0.907445, 0.756276, 0.9985,  0.711226}, {0.920259, 0.169798, 0.785362, 0.893985,  0.485002}, {{3, 2, 2}, {0, 1, 1}, {1, 2, 4}, {2, 0, 3}, {2, 1,  2}, {2, 1, 2}, {0, 0, 3}, {3, 2, 2}}, 0.635805, 0.902808,  0.514856, 0.258414, 0.0130317}, {2.89567, 0.973421, -0.642167,  0.0959426, 3.77236, 0.973421, 1.74265, -0.255471, 1.52433,  0.434439, -0.642167, -0.255471, 2.98822, -1.3489, 3.08913,  0.0959426, 1.52433, -1.3489, 2.34674, 0.583678, 3.77236, 0.434439,  3.08913, 0.583678, 2.8223, 2.76104, 4.10715, -2.51913, 0.818879,  2.79961, 4.10715, 2.71226, -0.96338,  4.70038, -3.30464, -2.51913, -0.96338, 2.71719, -1.17817, 1.68508,  0.818879, 4.70038, -1.17817, 2.74144, 1.12756, 2.79961, -3.30464,  1.68508, 1.12756, 1.93652, 3.10711, 2.54564, -0.297732, 0.373113,  0.604332, 2.54564,  4.00412, -3.92132, -0.708278, -0.192263, -0.297732, -3.92132,  2.1433, -4.22133, 1.45877, 0.373113, -0.708278, -4.22133, 2.42083,  1.06591, 0.604332, -0.192263, 1.45877, 1.06591, 3.0062, 3.02912,  0.479008, -2.2332, 4.79045, 4.13135, 0.479008, 2.98664, -1.17766,  3.07608, 0.971912, -2.2332, -1.17766, 1.35059, -2.41848, 0.166336,  4.79045, 3.07608, -2.41848, 2.9829, 2.72938, 4.13135, 0.971912,  0.166336, 2.72938, 2.84677}}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      double dalpha[4*5*5];
      double dlogbeta[3];
      double dgamma[5*5];
      ParameterizedNormalDistribution prior_alpha = 
        parameterized_normal_distribution (data[i].inputs.alphastddev);
      NormalDistribution prior_logbeta = 
        normal_distribution (data[i].inputs.logbetamean, 
                             data[i].inputs.logbetastddev);
      NormalDistribution prior_gamma = 
        normal_distribution (data[i].inputs.gammamean, 
                             data[i].inputs.gammastddev);

      memset (dalpha, lrand48 (), 4*5*5 * sizeof (dalpha[0]));

      for (unsigned int j = 0; j < 4; ++j)
        {
          for (unsigned int k = 0; k < 5; ++k)
            {
              data[i].inputs.alpha[j * 5 * 5 + k * 5 + k] = drand48 ();
            }
        }

      for (unsigned int k = 0; k < 5; ++k)
        {
          data[i].inputs.gamma[k * 5 + k] = drand48 ();
        }

      dqfunc (dalpha,
              dlogbeta,
              dgamma,
              data[i].inputs.alpha,
              4,
              5,
              data[i].inputs.logbeta,
              3,
              data[i].inputs.gamma,
              data[i].inputs.pz,
              data[i].inputs.ratings,
              8,
              &prior_alpha.base,
              &prior_logbeta.base,
              &prior_gamma.base,
              1);

      for (unsigned int j = 0; j < 4*5*5; ++j)
        {
          if (j % 5 <= (j / 5) % 5)
            {
              assert (dalpha[j] == 0.0 || 
                      (fprintf (stderr, "%u %u: %g ?= 0\n", i, j, dalpha[j]), 
                       0));
            }
          else
            {
              assert (fabs (dalpha[j] - data[i].dalpha[j]) <=
                      5e-5 * (1 + fabs (dalpha[j]) + fabs (data[i].dalpha[j])) ||
                      (fprintf (stderr, "%u %u: %g ?= %g\n", i, j, dalpha[j], data[i].dalpha[j]),
                       0));
            }
        }
    }
}

typedef struct _DqfuncDlogbetaTestDatum DqfuncDlogbetaTestDatum;
struct _DqfuncDlogbetaTestDatum 
{ 
  struct
    {
      double    alpha[4 * 5 * 5];
      double    logbeta[3];
      double    gamma[5 * 5];
      double    pz[3 * 5];
      double    priorz[5];
      Rating    ratings[8];
      double    alphastddev;
      double    logbetamean;
      double    logbetastddev;
      double    gammamean;
      double    gammastddev;
    }                   inputs;
  double                desired_output[3];
};

static void
test_dqfuncdlogbeta (void)
{
  DqfuncDlogbetaTestDatum data[] = 
    {{{{0, 0.263497, 0.672462, 0.0649254, 0.24516, 0.0194678, 0, 0.815535,  0.711145, 0.168997, 0.85216, 0.836163, 0, 0.803701, 0.41272,  0.853661, 0.124937, 0.883442, 0, 0.242922, 0.0682983, 0.230952,  0.39844, 0.607117, 0, 0, 0.16549, 0.716096, 0.140025, 0.594086,  0.901993, 0, 0.0436339, 0.0751, 0.348925, 0.882525, 0.228099, 0,  0.363955, 0.179929, 0.0303649, 0.391936, 0.560254, 0, 0.767208,  0.176704, 0.266999, 0.676812, 0.524286, 0, 0, 0.108406, 0.0360471,  0.278373, 0.917169, 0.942916, 0, 0.319951, 0.138347, 0.323084,  0.0409226, 0.276317, 0, 0.0632473, 0.974158, 0.158397, 0.0482183,  0.699293, 0, 0.794229, 0.128032, 0.656282, 0.139038, 0.0270208, 0,  0, 0.951328, 0.389283, 0.462226, 0.502734, 0.842923, 0, 0.353236,  0.183853, 0.585565, 0.900007, 0.033285, 0, 0.0455062, 0.262482,  0.859085, 0.756968, 0.982259, 0, 0.288324, 0.700687, 0.708749,  0.282966, 0.494094, 0}, {0.572655, 0.0524671, 0.143928}, {1.,  0.467073, 0.621326, 0.663184, 0.681702, 0.964339, 1., 0.778404,  0.309947, 0.497848, 0.378774, 0.878397, 1., 0.276662, 0.452342,  0.116292, 0.0193122, 0.519695, 1., 0.470083, 0.827968, 0.318625,  0.810946, 0.187117, 1.}, {0.333874, 0.74597, 0.758479, 0.0431891,  0.866801, 0.124644, 0.0952948, 0.361487, 0.902462, 0.34624,  0.785347, 0.863639, 0.523688, 0.467843, 0.508685}, {0.411297,  0.407396, 0.448531, 0.98899,  0.941214}, {{3, 1, 4}, {2, 0, 1}, {1, 0, 0}, {2, 0, 1}, {1, 1,  0}, {2, 1, 1}, {1, 1, 1}, {3, 1, 3}}, 0.579428, 0.129906,  0.178044, 0.754097, 0.245554}, {-17.1482,  2.86704, -0.442334}}, {{{0, 0.383936, 0.419566, 0.710908, 0.378753,  0.259292, 0, 0.324271, 0.34942, 0.476292, 0.913052, 0.538924, 0,  0.485781, 0.952604, 0.445209, 0.0302389, 0.0744845, 0, 0.545208,  0.996678, 0.0412489, 0.133271, 0.96578, 0, 0, 0.866772, 0.863205,  0.379174, 0.720227, 0.482836, 0, 0.443639, 0.668267, 0.341474,  0.223544, 0.119368, 0, 0.318846, 0.865182, 0.310491, 0.580444,  0.833065, 0, 0.912578, 0.865282, 0.550205, 0.758581, 0.36737, 0,  0, 0.868604, 0.508956, 0.62531, 0.40159, 0.00183198, 0, 0.645752,  0.246136, 0.681363, 0.518996, 0.202113, 0, 0.577869, 0.33989,  0.295452, 0.0827451, 0.259022, 0, 0.474708, 0.984961, 0.502301,  0.425957, 0.56213, 0, 0, 0.119679, 0.952096, 0.667377, 0.19476,  0.251075, 0, 0.443139, 0.042067, 0.79317, 0.249243, 0.797387, 0,  0.795931, 0.111807, 0.730247, 0.595274, 0.218063, 0, 0.771917,  0.434795, 0.512529, 0.95904, 0.297209, 0}, {0.449834, 0.0102285,  0.533083}, {1., 0.73508, 0.330155, 0.058133, 0.865706, 0.54032,  1., 0.0790799, 0.614994, 0.823639, 0.74715, 0.829837, 1.,  0.817607, 0.0277075, 0.635344, 0.0995901, 0.222332, 1., 0.809645,  0.863427, 0.664795, 0.709803, 0.850605, 1.}, {0.566217, 0.214962,  0.699574, 0.317522, 0.831137, 0.884807, 0.641441, 0.451816,  0.290817, 0.805727, 0.0264475, 0.628177, 0.543667, 0.97589,  0.208841}, {0.60047, 0.908323, 0.8763, 0.986509,  0.790825}, {{1, 0, 3}, {2, 0, 2}, {2, 0, 0}, {3, 0, 4}, {3, 0,  0}, {2, 2, 4}, {0, 1, 4}, {3, 1, 4}}, 0.0448963, 0.211504,  0.276706, 0.94022, 0.478679}, {-4.30909,  2.2424, -5.20229}}, {{{0, 0.996543, 0.577132, 0.622698, 0.647542,  0.111736, 0, 0.93569, 0.170882, 0.356725, 0.306008, 0.909243, 0,  0.542704, 0.813058, 0.330118, 0.700402, 0.942234, 0, 0.904736,  0.453818, 0.713893, 0.151409, 0.859839, 0, 0, 0.242314, 0.437187,  0.211189, 0.38116, 0.245771, 0, 0.860055, 0.588491, 0.733618,  0.134036, 0.924365, 0, 0.417609, 0.376893, 0.828027, 0.0151218,  0.874905, 0, 0.563835, 0.497909, 0.31472, 0.932671, 0.659099, 0,  0, 0.0440904, 0.600827, 0.781262, 0.79926, 0.801776, 0, 0.16364,  0.570073, 0.4181, 0.556005, 0.303585, 0, 0.981582, 0.684482,  0.42197, 0.37922, 0.563973, 0, 0.307589, 0.593942, 0.364098,  0.689068, 0.743754, 0, 0, 0.0960335, 0.0493783, 0.756397,  0.0846545, 0.0519431, 0, 0.448551, 0.975135, 0.285395, 0.250167,  0.284912, 0, 0.405063, 0.867295, 0.694161, 0.981327, 0.423481, 0,  0.182813, 0.272192, 0.602107, 0.859508, 0.875224, 0}, {0.67825,  0.238008, 0.170441}, {1., 0.13147, 0.582216, 0.18863, 0.414044,  0.0468159, 1., 0.530273, 0.740079, 0.438908, 0.761421, 0.280106,  1., 0.455167, 0.0338455, 0.894127, 0.585945, 0.47384, 1.,  0.610365, 0.711314, 0.313753, 0.871734, 0.750856, 1.}, {0.83609,  0.635503, 0.633725, 0.580416, 0.704619, 0.0532872, 0.445095,  0.166372, 0.657803, 0.523014, 0.705017, 0.727464, 0.896382,  0.242908, 0.24985}, {0.693619, 0.00225502, 0.656963, 0.776009,  0.083254}, {{2, 1, 1}, {2, 2, 2}, {1, 0, 1}, {3, 1, 2}, {3, 1,  3}, {0, 2, 1}, {2, 1, 4}, {3, 0, 3}}, 0.290941, 0.34321,  0.904275, 0.332398,  0.454852}, {-3.65271, -0.743172, -0.752867}}, {{{0, 0.707707,  0.27055, 0.751982, 0.750233, 0.65442, 0, 0.825455, 0.585609,  0.0924295, 0.131406, 0.120438, 0, 0.858145, 0.196048, 0.888498,  0.870589, 0.164527, 0, 0.193793, 0.231535, 0.0945796, 0.0812726,  0.902852, 0, 0, 0.888324, 0.190304, 0.748875, 0.448, 0.180617, 0,  0.919754, 0.996893, 0.697767, 0.526198, 0.0942993, 0, 0.411284,  0.605338, 0.394792, 0.973861, 0.553139, 0, 0.40929, 0.506294,  0.103272, 0.388612, 0.215497, 0, 0, 0.27476, 0.0086928, 0.30734,  0.312646, 0.386435, 0, 0.818389, 0.558465, 0.864646, 0.205818,  0.898635, 0, 0.561571, 0.166879, 0.67962, 0.804335, 0.150287, 0,  0.561541, 0.284828, 0.830474, 0.597149, 0.152251, 0, 0, 0.778534,  0.727202, 0.208536, 0.936753, 0.503774, 0, 0.718509, 0.901197,  0.624107, 0.117339, 0.90012, 0, 0.342732, 0.759461, 0.911521,  0.0014859, 0.781161, 0, 0.592583, 0.231901, 0.197151, 0.630874,  0.0310419, 0}, {0.947073, 0.366676, 0.0337251}, {1., 0.878791,  0.168539, 0.639475, 0.825189, 0.942038, 1., 0.664765, 0.920966,  0.923992, 0.317931, 0.547426, 1., 0.0208451, 0.58126, 0.558469,  0.635905, 0.0193592, 1., 0.800099, 0.965886, 0.404004, 0.822209,  0.169225, 1.}, {0.934845, 0.456931, 0.455532, 0.1355, 0.0560533,  0.288392, 0.816058, 0.310311, 0.114015, 0.623627, 0.895092,  0.386319, 0.796085, 0.0762009, 0.874247}, {0.805059, 0.237616,  0.440296, 0.854888,  0.0049604}, {{0, 2, 2}, {1, 1, 4}, {1, 0, 1}, {1, 1, 0}, {2, 2,  0}, {0, 0, 3}, {2, 0, 2}, {2, 0, 4}}, 0.271729, 0.0362916,  0.0326793, 0.835735, 0.336885}, {-858.49, -309.97,  2.74471}}, {{{0, 0.57936, 0.577147, 0.700235, 0.280831, 0.290968,  0, 0.76109, 0.389923, 0.166816, 0.667341, 0.865998, 0, 0.0036038,  0.370731, 0.59114, 0.991751, 0.198544, 0, 0.133115, 0.150844,  0.136863, 0.193584, 0.861386, 0, 0, 0.114553, 0.104184, 0.357849,  0.524502, 0.535193, 0, 0.527036, 0.657614, 0.24367, 0.244224,  0.765947, 0, 0.267691, 0.0768545, 0.576883, 0.899949, 0.264087, 0,  0.706123, 0.985743, 0.908199, 0.0655429, 0.573008, 0, 0,  0.834899, 0.771336, 0.871959, 0.711622, 0.720346, 0, 0.667152,  0.51411, 0.18712, 0.185153, 0.140116, 0, 0.856496, 0.94345,  0.940929, 0.374169, 0.588805, 0, 0.866595, 0.364045, 0.47422,  0.324717, 0.160472, 0, 0, 0.378302, 0.566021, 0.259174, 0.587464,  0.543403, 0, 0.794686, 0.387215, 0.875842, 0.823058, 0.127533, 0,  0.873105, 0.688722, 0.637904, 0.987417, 0.0166096, 0, 0.745273,  0.696976, 0.613248, 0.427805, 0.878678, 0}, {0.33293, 0.139028,  0.103088}, {1., 0.718206, 0.954628, 0.573007, 0.843913, 0.130742,  1., 0.411225, 0.778321, 0.456698, 0.2549, 0.588167, 1., 0.650788,  0.583592, 0.566178, 0.950263, 0.66337, 1., 0.566983, 0.820905,  0.253287, 0.0501222, 0.139178, 1.}, {0.942227, 0.920357, 0.911094,  0.0360901, 0.224021, 0.965729, 0.338087, 0.192177, 0.093279,  0.554504, 0.559766, 0.735479, 0.838379, 0.966336,  0.908978}, {0.151887, 0.272201, 0.0160736, 0.245608,  0.584905}, {{3, 1, 2}, {1, 0, 3}, {3, 1, 1}, {2, 1, 0}, {1, 0,  0}, {2, 2, 4}, {1, 2, 2}, {3, 1, 0}}, 0.451296, 0.762786,  0.195486, 0.445727, 0.509068}, {10.0174, 16.1076,  16.8257}}, {{{0, 0.84243, 0.284392, 0.409637, 0.285047, 0.876701,  0, 0.946304, 0.21746, 0.191768, 0.322197, 0.386538, 0, 0.48198,  0.353389, 0.355861, 0.47756, 0.330093, 0, 0.0811882, 0.339787,  0.231952, 0.745189, 0.629892, 0, 0, 0.577001, 0.036466, 0.299462,  0.120824, 0.734571, 0, 0.752074, 0.889825, 0.835777, 0.85787,  0.80577, 0, 0.672365, 0.644009, 0.535673, 0.419232, 0.190385, 0,  0.29062, 0.179812, 0.941672, 0.860292, 0.209432, 0, 0, 0.840024,  0.70972, 0.115103, 0.57954, 0.263023, 0, 0.673254, 0.815641,  0.458716, 0.528452, 0.92118, 0, 0.925816, 0.622938, 0.670582,  0.11541, 0.25345, 0, 0.978929, 0.13491, 0.696178, 0.0630653,  0.688308, 0, 0, 0.955098, 0.754507, 0.202774, 0.478876, 0.115074,  0, 0.0447865, 0.087671, 0.899336, 0.852051, 0.371533, 0, 0.27203,  0.440621, 0.323598, 0.450353, 0.346215, 0, 0.817683, 0.653016,  0.334943, 0.0927646, 0.838754, 0}, {0.518107, 0.638765,  0.0296993}, {1., 0.150445, 0.563009, 0.884258, 0.826926, 0.671569,  1., 0.447935, 0.839472, 0.739255, 0.772233, 0.595885, 1.,  0.467939, 0.467224, 0.331612, 0.272286, 0.0175862, 1., 0.121009,  0.513929, 0.61927, 0.682643, 0.0282448, 1.}, {0.675175, 0.101163,  0.0438786, 0.998545, 0.52473, 0.538154, 0.15962, 0.17162,  0.853161, 0.0902186, 0.320149, 0.432365, 0.0809282, 0.494334,  0.85221}, {0.965141, 0.749317, 0.222048, 0.834624,  0.844132}, {{0, 1, 3}, {2, 2, 0}, {3, 2, 0}, {0, 0, 0}, {3, 1,  4}, {2, 0, 3}, {0, 1, 4}, {1, 0, 1}}, 0.235388, 0.602778,  0.15198, 0.815887, 0.560212}, {2.08676, -2.77853,  24.5956}}, {{{0, 0.501616, 0.108102, 0.817341, 0.0354825, 0.963462,  0, 0.948481, 0.645721, 0.182322, 0.873243, 0.628332, 0, 0.213356,  0.101393, 0.378909, 0.776123, 0.248215, 0, 0.352077, 0.156861,  0.941499, 0.404083, 0.116689, 0, 0, 0.554083, 0.789519, 0.588197,  0.556477, 0.0524674, 0, 0.681417, 0.770855, 0.520994, 0.0890056,  0.732935, 0, 0.125134, 0.338673, 0.215762, 0.104603, 0.911778, 0,  0.237279, 0.836853, 0.32848, 0.663563, 0.885203, 0, 0, 0.679992,  0.386982, 0.259479, 0.768513, 0.125909, 0, 0.597463, 0.671283,  0.212036, 0.073442, 0.916046, 0, 0.900428, 0.691042, 0.984436,  0.183111, 0.775294, 0, 0.352369, 0.768674, 0.0785076, 0.863516,  0.11509, 0, 0, 0.931821, 0.750027, 0.199953, 0.229887, 0.251828,  0, 0.363046, 0.940474, 0.461374, 0.125919, 0.765583, 0, 0.269191,  0.249337, 0.0524769, 0.849536, 0.368763, 0, 0.558295, 0.0680405,  0.666426, 0.593469, 0.205926, 0}, {0.299367, 0.587918,  0.729954}, {1., 0.0908368, 0.367546, 0.837891, 0.530001, 0.86095,  1., 0.115718, 0.474846, 0.589527, 0.399576, 0.989799, 1.,  0.709263, 0.320336, 0.150239, 0.937322, 0.859726, 1., 0.951573,  0.591943, 0.869282, 0.193301, 0.358104, 1.}, {0.386017, 0.569915,  0.605382, 0.62815, 0.29518, 0.202369, 0.767491, 0.0981496,  0.43423, 0.0866511, 0.292646, 0.508623, 0.0346541, 0.0968522,  0.583383}, {0.188286, 0.884415, 0.15953, 0.723656,  0.236713}, {{1, 0, 1}, {3, 0, 0}, {0, 2, 1}, {2, 0, 3}, {3, 1,  4}, {1, 0, 3}, {1, 1, 1}, {0, 1, 2}}, 0.292472, 0.290249,  0.530356, 0.878609,  0.906455}, {-0.810016, -2.30666, -2.59884}}, {{{0, 0.720334,  0.924973, 0.250459, 0.611275, 0.517965, 0, 0.157482, 0.152309,  0.177045, 0.431313, 0.864836, 0, 0.643686, 0.142391, 0.334461,  0.281454, 0.4554, 0, 0.257975, 0.174931, 0.557797, 0.218688,  0.965504, 0, 0, 0.884683, 0.0274418, 0.340079, 0.0590485,  0.164349, 0, 0.102468, 0.0896199, 0.447773, 0.646384, 0.944986, 0,  0.937311, 0.270729, 0.215071, 0.0801498, 0.293624, 0, 0.128338,  0.88061, 0.798696, 0.838224, 0.870362, 0, 0, 0.705679, 0.240899,  0.619537, 0.904859, 0.820996, 0, 0.213457, 0.279458, 0.84581,  0.656647, 0.110988, 0, 0.189838, 0.398037, 0.0102628, 0.166002,  0.252527, 0, 0.127308, 0.795192, 0.0858523, 0.958903, 0.99897, 0,  0, 0.914582, 0.287156, 0.120679, 0.128608, 0.208903, 0, 0.0462576,  0.501142, 0.223749, 0.387907, 0.832801, 0, 0.221684, 0.377939,  0.73126, 0.721812, 0.0318461, 0, 0.979902, 0.720997, 0.55581,  0.779319, 0.852594, 0}, {0.925806, 0.469958, 0.820416}, {1.,  0.853623, 0.0112235, 0.182802, 0.699737, 0.725015, 1., 0.80232,  0.136544, 0.198595, 0.501266, 0.414413, 1., 0.303743, 0.976911,  0.123328, 0.683152, 0.581931, 1., 0.945065, 0.143426, 0.962155,  0.0261207, 0.165746, 1.}, {0.290832, 0.0363493, 0.556163, 0.34533,  0.437209, 0.0251258, 0.373361, 0.645593, 0.712194, 0.222806,  0.236816, 0.446997, 0.210927, 0.808393, 0.933073}, {0.470086,  0.0875995, 0.125241, 0.351142,  0.525021}, {{0, 2, 0}, {1, 2, 3}, {3, 1, 4}, {1, 2, 1}, {3, 1,  2}, {1, 2, 0}, {2, 0, 0}, {1, 1, 0}}, 0.944174, 0.163086,  0.325021, 0.359275,  0.653341}, {-8.43173, -3.92598, -11.2887}}, {{{0, 0.126736,  0.768859, 0.0139445, 0.216132, 0.101611, 0, 0.395498, 0.368352,  0.503939, 0.878805, 0.158682, 0, 0.921354, 0.293011, 0.0704118,  0.225608, 0.451268, 0, 0.205412, 0.945171, 0.874466, 0.926247,  0.261238, 0, 0, 0.782085, 0.549445, 0.566973, 0.607897, 0.655349,  0, 0.780586, 0.553028, 0.391765, 0.553738, 0.385088, 0, 0.184676,  0.887826, 0.674933, 0.226407, 0.263322, 0, 0.594815, 0.604521,  0.000798403, 0.812054, 0.389403, 0, 0, 0.65935, 0.126332,  0.885806, 0.128165, 0.877265, 0, 0.576887, 0.318834, 0.520268,  0.221916, 0.7963, 0, 0.765806, 0.128503, 0.668178, 0.411212,  0.581129, 0, 0.240677, 0.993245, 0.184805, 0.317807, 0.645862, 0,  0, 0.388723, 0.184007, 0.505754, 0.256458, 0.729373, 0, 0.0576747,  0.619947, 0.128293, 0.852108, 0.480788, 0, 0.301114, 0.608025,  0.630192, 0.684488, 0.535308, 0, 0.479522, 0.962014, 0.273276,  0.954179, 0.238846, 0}, {0.968769, 0.0884706, 0.636372}, {1.,  0.592984, 0.580045, 0.904464, 0.130618, 0.336526, 1., 0.850672,  0.846789, 0.510671, 0.208233, 0.998564, 1., 0.366001, 0.209557,  0.600207, 0.368372, 0.681514, 1., 0.674249, 0.120685, 0.406359,  0.408238, 0.72007, 1.}, {0.88184, 0.43759, 0.319767, 0.0836981,  0.288856, 0.857544, 0.415304, 0.95308, 0.95233, 0.00687218,  0.568514, 0.44241, 0.744097, 0.00830809, 0.202513}, {0.232853,  0.14389, 0.639936, 0.520999,  0.558604}, {{0, 1, 4}, {1, 0, 0}, {1, 0, 2}, {1, 2, 3}, {3, 2,  0}, {3, 2, 1}, {1, 0, 3}, {2, 0, 2}}, 0.0232046, 0.233577,  0.112761, 0.838534, 0.141365}, {-61.5944,  11.2076, -33.7545}}, {{{0, 0.795988, 0.792994, 0.754836, 0.852509,  0.938443, 0, 0.37769, 0.801756, 0.90018, 0.931571, 0.809176, 0,  0.359346, 0.156082, 0.923263, 0.606663, 0.126494, 0, 0.0121926,  0.283327, 0.0856637, 0.56789, 0.988988, 0, 0, 0.0497498, 0.972902,  0.729356, 0.847623, 0.253762, 0, 0.179908, 0.97452, 0.995114,  0.315319, 0.802218, 0, 0.172764, 0.0949341, 0.383748, 0.993042,  0.813417, 0, 0.938852, 0.460485, 0.386378, 0.686923, 0.926659, 0,  0, 0.177158, 0.300715, 0.119033, 0.937671, 0.127408, 0, 0.327813,  0.389678, 0.0900482, 0.873646, 0.147904, 0, 0.415158, 0.0949345,  0.558327, 0.345687, 0.242395, 0, 3.34151e-7, 0.174579,  0.352645, 0.428978, 0.0611486, 0, 0, 0.714094, 0.966266, 0.742054,  0.134489, 0.536936, 0, 0.665552, 0.623021, 0.196818, 0.409529,  0.337739, 0, 0.233343, 0.10677, 0.535883, 0.189835, 0.818185, 0,  0.0118356, 0.977556, 0.844148, 0.575791, 0.0118352, 0}, {0.802977,  0.491503, 0.146813}, {1., 0.950687, 0.0888832, 0.525237,  0.404759, 0.816197, 1., 0.551947, 0.859685, 0.781738, 0.619379,  0.142418, 1., 0.521946, 0.548394, 0.512609, 0.606535, 0.332111,  1., 0.730209, 0.500773, 0.628979, 0.487963, 0.154418,  1.}, {0.488938, 0.826002, 0.99646, 0.00760503, 0.538252, 0.737119,  0.471223, 0.602846, 0.722054, 0.185172, 0.611538, 0.821108,  0.102675, 0.0427538, 0.089592}, {0.272714, 0.590066, 0.436218,  0.757481,  0.542505}, {{3, 1, 4}, {1, 2, 1}, {2, 2, 1}, {3, 2, 0}, {3, 1,  4}, {1, 1, 4}, {3, 2, 3}, {2, 0, 0}}, 0.0892927, 0.807239,  0.269518, 0.388086, 0.600354}, {-1.38704, 3.73673, 9.0268}}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      double dalpha[4*5*5];
      double dlogbeta[3];
      double dgamma[5*5];
      ParameterizedNormalDistribution prior_alpha = 
        parameterized_normal_distribution (data[i].inputs.alphastddev);
      NormalDistribution prior_logbeta = 
        normal_distribution (data[i].inputs.logbetamean, 
                             data[i].inputs.logbetastddev);
      NormalDistribution prior_gamma = 
        normal_distribution (data[i].inputs.gammamean, 
                             data[i].inputs.gammastddev);

      memset (dlogbeta, lrand48 (), 3 * sizeof (dlogbeta[0]));

      for (unsigned int j = 0; j < 4; ++j)
        {
          for (unsigned int k = 0; k < 5; ++k)
            {
              data[i].inputs.alpha[j * 5 * 5 + k * 5 + k] = drand48 ();
            }
        }

      for (unsigned int k = 0; k < 5; ++k)
        {
          data[i].inputs.gamma[k * 5 + k] = drand48 ();
        }

      dqfunc (dalpha,
              dlogbeta,
              dgamma,
              data[i].inputs.alpha,
              4,
              5,
              data[i].inputs.logbeta,
              3,
              data[i].inputs.gamma,
              data[i].inputs.pz,
              data[i].inputs.ratings,
              8,
              &prior_alpha.base,
              &prior_logbeta.base,
              &prior_gamma.base,
              0);

      for (unsigned int j = 0; j < 3; ++j)
        {
          assert (fabs (dlogbeta[j] - data[i].desired_output[j]) <=
                  1e-5 * (1 + fabs (dlogbeta[j]) + fabs (data[i].desired_output[j])) ||
                  (fprintf (stderr, "%u %u: %g ?= %g\n", i, j, dlogbeta[j], data[i].desired_output[j]),
                   0));
        }
    }
}

static void
test_dqfuncdlogbeta_symmetric (void)
{
  DqfuncDlogbetaTestDatum data[] = 
    {{{{0, 0.981237, 0.273058, 0.380481, 0.062103, 0.244118, 0, 0.801835,  0.777635, 0.340049, 0.0589459, 0.190297, 0, 0.956527, 0.237374,  0.0161921, 0.100705, 0.683813, 0, 0.647307, 0.579974, 0.343224,  0.141309, 0.558015, 0, 0, 0.772735, 0.0737065, 0.753223, 0.95766,  0.791498, 0, 0.800648, 0.372741, 0.895557, 0.54738, 0.998813, 0,  0.595106, 0.555509, 0.488434, 0.808516, 0.638579, 0, 0.318135,  0.472242, 0.707811, 0.954766, 0.670828, 0, 0, 0.892268, 0.364587,  0.813457, 0.112813, 0.119533, 0, 0.29088, 0.0602348, 0.155153,  0.328035, 0.490232, 0, 0.687493, 0.259595, 0.780656, 0.491418,  0.0923872, 0, 0.704087, 0.292222, 0.682902, 0.453808, 0.385952, 0,  0, 0.81998, 0.975091, 0.499042, 0.715124, 0.927712, 0, 0.610505,  0.685585, 0.602311, 0.808179, 0.319625, 0, 0.62535, 0.447159,  0.480144, 0.829393, 0.937856, 0, 0.187563, 0.699488, 0.337974,  0.845469, 0.483476, 0}, {0.407266, 0.655072, 0.391661}, {1.,  0.0975243, 0.587286, 0.679981, 0.89262, 0.3824, 1., 0.659574,  0.069476, 0.207035, 0.780088, 0.851394, 1., 0.749851, 0.581685,  0.33293, 0.371251, 0.920459, 1., 0.643829, 0.145366, 0.671763,  0.582484, 0.79836, 1.}, {0.66189, 0.264497, 0.927412, 0.406698,  0.564366, 0.677211, 0.247431, 0.514079, 0.181966, 0.0176372,  0.177955, 0.307044, 0.401877, 0.166243, 0.428104}, {0.725359,  0.0689478, 0.794992, 0.507646,  0.0815296}, {{1, 2, 0}, {0, 1, 2}, {0, 0, 0}, {1, 1, 2}, {2, 2,  4}, {3, 2, 1}, {2, 2, 2}, {1, 0, 2}}, 0.923581, 0.123229,  0.925161, 0.28317,  0.261691}, {-0.208318, -0.882743, -1.20209}}, {{{0, 0.858733,  0.997749, 0.876471, 0.697325, 0.181522, 0, 0.750318, 0.362393,  0.515359, 0.163885, 0.572362, 0, 0.0553487, 0.113482, 0.997642,  0.144258, 0.32999, 0, 0.0445342, 0.20265, 0.636613, 0.248461,  0.120953, 0, 0, 0.0794204, 0.711451, 0.965291, 0.859262, 0.220688,  0, 0.713702, 0.0888191, 0.161936, 0.0391658, 0.963384, 0,  0.726427, 0.646577, 0.875281, 0.391022, 0.671078, 0, 0.533095,  0.877639, 0.246764, 0.341088, 0.488561, 0, 0, 0.674989, 0.610151,  0.0926271, 0.367608, 0.595569, 0, 0.898699, 0.127336, 0.508346,  0.374881, 0.184997, 0, 0.0385174, 0.34641, 0.335716, 0.221613,  0.312091, 0, 0.699833, 0.460434, 0.830591, 0.641013, 0.166738, 0,  0, 0.582795, 0.583828, 0.299925, 0.678177, 0.907806, 0, 0.973677,  0.207298, 0.31057, 0.312237, 0.0749775, 0, 0.0799619, 0.802224,  0.937355, 0.88998, 0.0414445, 0, 0.455814, 0.60164, 0.668367,  0.729354, 0.755981, 0}, {0.141205, 0.837776, 0.0883406}, {1.,  0.589243, 0.55841, 0.253948, 0.788415, 0.911066, 1., 0.650604,  0.280271, 0.581117, 0.600496, 0.338368, 1., 0.205294, 0.501155,  0.798273, 0.401012, 0.315314, 1., 0.45971, 0.342459, 0.799373,  0.646947, 0.730357, 1.}, {0.586478, 0.658167, 0.809171, 0.642016,  0.997235, 0.0997571, 0.555223, 0.853601, 0.0861687, 0.449153,  0.274951, 0.272484, 0.485672, 0.110785, 0.0696576}, {0.771329,  0.6874, 0.709772, 0.754344,  0.311619}, {{2, 1, 2}, {3, 1, 2}, {0, 0, 4}, {1, 1, 2}, {2, 0,  4}, {3, 2, 3}, {1, 2, 3}, {2, 2, 3}}, 0.344941, 0.9104, 0.107397,  0.581262, 0.758463}, {66.5227, 3.51649,  71.3913}}, {{{0, 0.252232, 0.298227, 0.939246, 0.761228, 0.152475,  0, 0.743004, 0.0856448, 0.67506, 0.703323, 0.468053, 0, 0.813161,  0.189387, 0.592538, 0.398395, 0.0418312, 0, 0.501988, 0.882766,  0.644051, 0.730212, 0.157047, 0, 0, 0.972366, 0.536654, 0.14895,  0.398584, 0.720133, 0, 0.238427, 0.209704, 0.637355, 0.567658,  0.495423, 0, 0.124059, 0.962296, 0.864335, 0.0273704, 0.310899, 0,  0.772908, 0.271797, 0.628975, 0.269068, 0.270921, 0, 0, 0.389032,  0.984924, 0.538855, 0.113874, 0.416666, 0, 0.448271, 0.389905,  0.71529, 0.696533, 0.209844, 0, 0.180201, 0.077935, 0.128875,  0.714421, 0.0561415, 0, 0.115639, 0.264539, 0.687051, 0.745243,  0.342731, 0, 0, 0.992742, 0.0580753, 0.476175, 0.0718101,  0.603711, 0, 0.0731508, 0.93732, 0.957936, 0.187045, 0.62488, 0,  0.547414, 0.242646, 0.490512, 0.415036, 0.367213, 0, 0.164711,  0.361638, 0.700615, 0.311072, 0.0490714, 0}, {0.0970981,  0.0135642, 0.565829}, {1., 0.70634, 0.104356, 0.955489, 0.0896543,  0.63453, 1., 0.500645, 0.882338, 0.152335, 0.676594, 0.313601,  1., 0.257458, 0.60492, 0.433948, 0.823088, 0.842422, 1., 0.237707,  0.269238, 0.461451, 0.141807, 0.926635, 1.}, {0.220166, 0.364353,  0.128243, 0.360805, 0.513826, 0.259997, 0.172754, 0.271151,  0.879296, 0.759352, 0.290416, 0.118817, 0.202701, 0.445751,  0.0329579}, {0.513896, 0.768753, 0.622663, 0.190536,  0.27619}, {{2, 0, 0}, {2, 1, 2}, {3, 0, 4}, {0, 0, 3}, {3, 0,  1}, {2, 2, 1}, {2, 0, 2}, {1, 1, 1}}, 0.499515, 0.161212,  0.0487282, 0.349555, 0.279349}, {25.7836,  61.8353, -170.718}}, {{{0, 0.796859, 0.920485, 0.988749, 0.765523,  0.536862, 0, 0.747731, 0.717598, 0.886228, 0.77751, 0.457315, 0,  0.598782, 0.683526, 0.33176, 0.424357, 0.0848853, 0, 0.914773,  0.709097, 0.233821, 0.808696, 0.415258, 0, 0, 0.547885, 0.185093,  0.459141, 0.135909, 0.751027, 0, 0.264608, 0.470392, 0.370386,  0.214164, 0.516877, 0, 0.752794, 0.484159, 0.436654, 0.0595627,  0.154012, 0, 0.800633, 0.104894, 0.635206, 0.0691267, 0.885859, 0,  0, 0.395797, 0.401385, 0.260431, 0.470601, 0.847912, 0, 0.216292,  0.80129, 0.334692, 0.0968854, 0.951684, 0, 0.330898, 0.964306,  0.882721, 0.434807, 0.578105, 0, 0.480147, 0.446067, 0.375244,  0.424093, 0.679514, 0, 0, 0.341173, 0.740038, 0.354966, 0.793655,  0.945375, 0, 0.338653, 0.094535, 0.323054, 0.0974633, 0.122361, 0,  0.293245, 0.988362, 0.000577817, 0.170677, 0.962347, 0,  0.0240567, 0.117857, 0.735871, 0.384242, 0.54391, 0}, {0.67179,  0.360626, 0.960149}, {1., 0.864395, 0.330617, 0.620588, 0.605183,  0.0707403, 1., 0.385242, 0.281935, 0.510648, 0.747686, 0.287779,  1., 0.159574, 0.217403, 0.759324, 0.287201, 0.988897, 1.,  0.255056, 0.735267, 0.169344, 0.253026, 0.870815, 1.}, {0.191357,  0.497554, 0.8924, 0.910666, 0.326962, 0.166937, 0.271811,  0.305483, 0.256222, 0.781695, 0.989876, 0.794835, 0.508535,  0.493916, 0.830302}, {0.577432, 0.749211, 0.206715, 0.841405,  0.322376}, {{1, 1, 0}, {3, 1, 1}, {0, 2, 4}, {1, 1, 0}, {3, 2,  2}, {1, 0, 4}, {2, 1, 4}, {0, 2, 3}}, 0.0139441, 0.037371,  0.588379, 0.451562,  0.822587}, {-3.10176, -0.924327, -13.9698}}, {{{0, 0.539817,  0.695979, 0.540896, 0.495625, 0.37288, 0, 0.424168, 0.235413,  0.239403, 0.591185, 0.434292, 0, 0.440578, 0.730868, 0.0972686,  0.60399, 0.863145, 0, 0.981656, 0.890553, 0.762585, 0.540769,  0.967712, 0, 0, 0.853182, 0.174206, 0.0892077, 0.145126, 0.313366,  0, 0.478226, 0.548312, 0.649501, 0.940486, 0.0540582, 0,  0.312899, 0.410098, 0.349301, 0.619766, 0.872321, 0, 0.67923,  0.252033, 0.015776, 0.00917559, 0.697573, 0, 0, 0.361479,  0.253191, 0.468406, 0.729861, 0.508297, 0, 0.0789855, 0.379199,  0.584736, 0.194931, 0.600759, 0, 0.830887, 0.935235, 0.254445,  0.546701, 0.517988, 0, 0.525137, 0.905144, 0.926935, 0.645667,  0.845907, 0, 0, 0.653111, 0.911159, 0.636492, 0.148334, 0.291632,  0, 0.657968, 0.168085, 0.418473, 0.783335, 0.578982, 0, 0.788887,  0.833737, 0.588404, 0.978223, 0.958, 0, 0.898502, 0.333959,  0.431522, 0.440011, 0.373365, 0}, {0.428816, 0.504587,  0.794344}, {1., 0.527457, 0.775705, 0.593428, 0.157853, 0.379123,  1., 0.484073, 0.93546, 0.989768, 0.960651, 0.700738, 1., 0.356478,  0.200881, 0.126914, 0.112334, 0.378255, 1., 0.242882, 0.228412,  0.778375, 0.946733, 0.80287, 1.}, {0.855047, 0.349559, 0.442146,  0.0085257, 0.327589, 0.573854, 0.848718, 0.850673, 0.948466,  0.0897815, 0.913257, 0.860905, 0.987815, 0.389044,  0.556779}, {0.660024, 0.860901, 0.27671, 0.178524,  0.417143}, {{1, 0, 2}, {3, 2, 2}, {3, 0, 2}, {2, 0, 2}, {0, 1,  1}, {1, 2, 0}, {1, 2, 4}, {2, 2, 0}}, 0.63249, 0.498335,  0.231791, 0.614272,  0.777443}, {0.244862, -0.0238011, -10.7821}}, {{{0, 0.148776,  0.789646, 0.605747, 0.449854, 0.574922, 0, 0.940928, 0.755074,  0.501388, 0.48514, 0.027671, 0, 0.894169, 0.513573, 0.0960966,  0.470892, 0.234145, 0, 0.652671, 0.819387, 0.292368, 0.817002,  0.0201815, 0, 0, 0.321052, 0.0605763, 0.20273, 0.242738, 0.172276,  0, 0.270931, 0.596983, 0.792885, 0.597354, 0.330002, 0, 0.841909,  0.291497, 0.112214, 0.302331, 0.94774, 0, 0.777924, 0.0161171,  0.831439, 0.713596, 0.125253, 0, 0, 0.19673, 0.539072, 0.896594,  0.105071, 0.875679, 0, 0.478496, 0.693864, 0.862333, 0.703403,  0.207565, 0, 0.096881, 0.0694483, 0.106049, 0.877563, 0.254972, 0,  0.777951, 0.993835, 0.575231, 0.307232, 0.0000272016, 0, 0,  0.977718, 0.743792, 0.593636, 0.874774, 0.780988, 0, 0.20472,  0.697042, 0.769703, 0.905309, 0.726224, 0, 0.00317826, 0.90737,  0.201906, 0.518659, 0.906297, 0, 0.837922, 0.0958576, 0.641097,  0.651325, 0.0599701, 0}, {0.102022, 0.0658657, 0.344094}, {1.,  0.0599429, 0.124304, 0.322074, 0.750458, 0.185169, 1., 0.343316,  0.117354, 0.0534159, 0.415466, 0.438007, 1., 0.39113, 0.0502377,  0.508096, 0.236101, 0.872471, 1., 0.14394, 0.670174, 0.140243,  0.231374, 0.492615, 1.}, {0.610204, 0.0382206, 0.165508, 0.148521,  0.550261, 0.913916, 0.843434, 0.398063, 0.365093, 0.5706,  0.72608, 0.344647, 0.949627, 0.132593, 0.33495}, {0.294409,  0.441531, 0.896492, 0.462479,  0.150469}, {{3, 0, 4}, {3, 0, 4}, {1, 2, 3}, {1, 0, 4}, {0, 1,  1}, {1, 1, 3}, {1, 2, 0}, {0, 1, 0}}, 0.771357, 0.756249,  0.231105, 0.657854, 0.161152}, {11.9142, 12.5245,  6.83471}}, {{{0, 0.718028, 0.0655973, 0.509333, 0.610891, 0.804112,  0, 0.222163, 0.11127, 0.245798, 0.233512, 0.496084, 0, 0.766623,  0.296171, 0.10092, 0.161134, 0.472214, 0, 0.85464, 0.204427,  0.698655, 0.321745, 0.0832831, 0, 0, 0.448178, 0.46755, 0.663891,  0.922131, 0.73015, 0, 0.401953, 0.154558, 0.31124, 0.926038,  0.179789, 0, 0.0432879, 0.0654422, 0.692526, 0.683705, 0.276665,  0, 0.769271, 0.591606, 0.522571, 0.804451, 0.914632, 0, 0,  0.387179, 0.823916, 0.482707, 0.831348, 0.939, 0, 0.356366,  0.818816, 0.909218, 0.20885, 0.954413, 0, 0.664258, 0.597977,  0.282812, 0.774624, 0.620971, 0, 0.532535, 0.590287, 0.0909187,  0.344306, 0.763264, 0, 0, 0.998681, 0.568347, 0.539854, 0.848632,  0.611502, 0, 0.744431, 0.0571472, 0.0172838, 0.672502, 0.388065,  0, 0.238331, 0.108066, 0.463651, 0.433652, 0.574072, 0, 0.510089,  0.180839, 0.659028, 0.953102, 0.977554, 0}, {0.590552, 0.568109,  0.608796}, {1., 0.21429, 0.591871, 0.999762, 0.0689421, 0.365657,  1., 0.98037, 0.25533, 0.0117949, 0.348374, 0.307868, 1., 0.867265,  0.773464, 0.240307, 0.844217, 0.433613, 1., 0.199392, 0.730219,  0.663378, 0.774585, 0.24629, 1.}, {0.752665, 0.0728257, 0.206476,  0.637493, 0.538375, 0.480954, 0.206714, 0.568551, 0.172718,  0.500585, 0.951384, 0.556756, 0.824345, 0.192717,  0.0841195}, {0.783292, 0.584037, 0.3485, 0.650507,  0.583901}, {{3, 2, 3}, {0, 2, 4}, {3, 2, 4}, {2, 0, 0}, {1, 2,  4}, {3, 1, 2}, {1, 0, 3}, {0, 1, 2}}, 0.853819, 0.685122,  0.875922, 0.337611, 0.101154}, {-1.02256,  0.090642, -3.24705}}, {{{0, 0.612297, 0.669446, 0.700118, 0.562778,  0.131343, 0, 0.462732, 0.131566, 0.39006, 0.630758, 0.511348, 0,  0.57481, 0.565715, 0.438041, 0.427228, 0.791518, 0, 0.981678,  0.089541, 0.776721, 0.207617, 0.12786, 0, 0, 0.404419, 0.9008,  0.870006, 0.026706, 0.792122, 0, 0.231354, 0.169888, 0.463928,  0.660779, 0.768622, 0, 0.0383215, 0.0738679, 0.0300214, 0.257274,  0.463511, 0, 0.508152, 0.59198, 0.830046, 0.671994, 0.526474, 0,  0, 0.502439, 0.0533249, 0.464377, 0.398615, 0.0980207, 0,  0.152525, 0.594371, 0.371909, 0.305899, 0.921172, 0, 0.424483,  0.907981, 0.64512, 0.15255, 0.386161, 0, 0.834113, 0.615098,  0.895276, 0.92265, 0.32596, 0, 0, 0.023118, 0.0652295, 0.250656,  0.799486, 0.520679, 0, 0.0119047, 0.78628, 0.400871, 0.422658,  0.859379, 0, 0.191909, 0.0289628, 0.116759, 0.938208, 0.767426, 0,  0.120982, 0.47164, 0.785658, 0.381265, 0.286869, 0}, {0.856541,  0.890382, 0.458615}, {1., 0.960909, 0.833423, 0.825152, 0.207958,  0.161423, 1., 0.312745, 0.813248, 0.421679, 0.760552, 0.890087,  1., 0.953868, 0.22977, 0.731589, 0.773327, 0.0156608, 1.,  0.462344, 0.610607, 0.301688, 0.230003, 0.0810792, 1.}, {0.323737,  0.445147, 0.339621, 0.622464, 0.362828, 0.611723, 0.514469,  0.414506, 0.201405, 0.298979, 0.701221, 0.992827, 0.440853,  0.408892, 0.747353}, {0.763057, 0.709265, 0.635565, 0.731692,  0.300713}, {{2, 2, 0}, {0, 2, 3}, {1, 1, 4}, {1, 0, 2}, {1, 2,  4}, {3, 2, 0}, {1, 2, 4}, {0, 0, 0}}, 0.098658, 0.333877,  0.501689, 0.219634,  0.774921}, {-3.90471, -2.45448, -2.54275}}, {{{0, 0.88873,  0.162068, 0.59717, 0.412093, 0.277007, 0, 0.647599, 0.182664,  0.210688, 0.978028, 0.946377, 0, 0.189837, 0.769834, 0.569136,  0.199024, 0.426779, 0, 0.0605696, 0.933572, 0.467332, 0.126066,  0.961912, 0, 0, 0.599695, 0.965643, 0.906432, 0.186991, 0.710965,  0, 0.803575, 0.309262, 0.774898, 0.433957, 0.155977, 0, 0.126598,  0.56421, 0.455929, 0.209599, 0.936761, 0, 0.794376, 0.886793,  0.0105752, 0.509982, 0.733807, 0, 0, 0.953221, 0.543243, 0.383916,  0.771895, 0.353526, 0, 0.577601, 0.477484, 0.584904, 0.642561,  0.774025, 0, 0.168222, 0.810006, 0.208604, 0.618049, 0.0416244, 0,  0.245796, 0.752675, 0.40845, 0.104863, 0.45142, 0, 0, 0.865882,  0.397874, 0.594881, 0.717613, 0.912662, 0, 0.854631, 0.210965,  0.945718, 0.559136, 0.277031, 0, 0.733481, 0.360814, 0.916574,  0.503005, 0.565258, 0, 0.550808, 0.70797, 0.884956, 0.523634,  0.305012, 0}, {0.955295, 0.476507, 0.418771}, {1., 0.853592,  0.0894131, 0.0786321, 0.82389, 0.135979, 1., 0.176752, 0.224001,  0.612925, 0.190261, 0.617616, 1., 0.94697, 0.879444, 0.829447,  0.701042, 0.443965, 1., 0.314186, 0.278639, 0.993071, 0.559009,  0.790552, 1.}, {0.973627, 0.0377758, 0.0825027, 0.371782,  0.120035, 0.948363, 0.00387055, 0.547892, 0.984056, 0.771611,  0.77987, 0.934967, 0.793795, 0.153995, 0.832899}, {0.0555229,  0.964348, 0.452954, 0.388934,  0.741337}, {{1, 0, 0}, {3, 1, 3}, {3, 1, 3}, {3, 1, 2}, {3, 0,  4}, {2, 0, 4}, {3, 0, 0}, {3, 2, 3}}, 0.685709, 0.459882,  0.829925, 0.950785,  0.712082}, {-4.03101, -1.56029, -0.701063}}, {{{0, 0.422107,  0.747422, 0.579003, 0.592047, 0.473744, 0, 0.743551, 0.0311112,  0.607991, 0.702133, 0.963682, 0, 0.0961441, 0.814196, 0.548137,  0.130783, 0.0406211, 0, 0.849847, 0.0951836, 0.741849, 0.299284,  0.164138, 0, 0, 0.635301, 0.911924, 0.3485, 0.452056, 0.213195, 0,  0.164503, 0.769497, 0.860009, 0.739451, 0.420951, 0, 0.738385,  0.252018, 0.0373179, 0.457269, 0.642241, 0, 0.437822, 0.489181,  0.326487, 0.60162, 0.587975, 0, 0, 0.393997, 0.584638, 0.302336,  0.423837, 0.758696, 0, 0.672713, 0.953836, 0.971782, 0.545501,  0.508211, 0, 0.18434, 0.111773, 0.806051, 0.0872595, 0.445954, 0,  0.859755, 0.768733, 0.62999, 0.803713, 0.421932, 0, 0, 0.279552,  0.303503, 0.202093, 0.833957, 0.885555, 0, 0.718865, 0.899757,  0.410119, 0.126859, 0.0461522, 0, 0.945921, 0.438338, 0.581358,  0.537941, 0.761581, 0, 0.326565, 0.775307, 0.450682, 0.315627,  0.466811, 0}, {0.00657442, 0.820692, 0.511914}, {1., 0.0448786,  0.727022, 0.517189, 0.309821, 0.210922, 1., 0.841467, 0.798323,  0.410063, 0.800802, 0.714608, 1., 0.752171, 0.464143, 0.362464,  0.13325, 0.214229, 1., 0.702561, 0.0358992, 0.357943, 0.763548,  0.386935, 1.}, {0.569088, 0.351368, 0.942856, 0.875021, 0.52421,  0.624346, 0.425667, 0.5652, 0.313288, 0.782879, 0.627344,  0.155137, 0.512486, 0.0682711, 0.875173}, {0.690994, 0.150021,  0.935021, 0.660944,  0.988433}, {{1, 0, 1}, {2, 0, 4}, {0, 2, 1}, {3, 0, 2}, {1, 1,  1}, {1, 2, 0}, {2, 0, 0}, {0, 1, 0}}, 0.114122, 0.577079,  0.897396, 0.601498, 0.545034}, {-0.780508, -3.36361, -1.25338}}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      double dalpha[4*5*5];
      double dlogbeta[3];
      double dgamma[5*5];
      ParameterizedNormalDistribution prior_alpha = 
        parameterized_normal_distribution (data[i].inputs.alphastddev);
      NormalDistribution prior_logbeta = 
        normal_distribution (data[i].inputs.logbetamean, 
                             data[i].inputs.logbetastddev);
      NormalDistribution prior_gamma = 
        normal_distribution (data[i].inputs.gammamean, 
                             data[i].inputs.gammastddev);

      memset (dlogbeta, lrand48 (), 3 * sizeof (dlogbeta[0]));

      for (unsigned int j = 0; j < 4; ++j)
        {
          for (unsigned int k = 0; k < 5; ++k)
            {
              data[i].inputs.alpha[j * 5 * 5 + k * 5 + k] = drand48 ();
            }
        }

      for (unsigned int k = 0; k < 5; ++k)
        {
          data[i].inputs.gamma[k * 5 + k] = drand48 ();
        }

      dqfunc (dalpha,
              dlogbeta,
              dgamma,
              data[i].inputs.alpha,
              4,
              5,
              data[i].inputs.logbeta,
              3,
              data[i].inputs.gamma,
              data[i].inputs.pz,
              data[i].inputs.ratings,
              8,
              &prior_alpha.base,
              &prior_logbeta.base,
              &prior_gamma.base,
              1);

      for (unsigned int j = 0; j < 3; ++j)
        {
          assert (fabs (dlogbeta[j] - data[i].desired_output[j]) <=
                  1e-5 * (1 + fabs (dlogbeta[j]) + fabs (data[i].desired_output[j])) ||
                  (fprintf (stderr, "%u %u: %g ?= %g\n", i, j, dlogbeta[j], data[i].desired_output[j]),
                   0));
        }
    }
}

typedef struct _DqfuncDgammaTestDatum DqfuncDgammaTestDatum;
struct _DqfuncDgammaTestDatum 
{ 
  struct
    {
      double    alpha[4 * 5 * 5];
      double    logbeta[3];
      double    gamma[5 * 5];
      double    pz[3 * 5];
      double    priorz[5];
      Rating    ratings[8];
      double    alphastddev;
      double    logbetamean;
      double    logbetastddev;
      double    gammamean;
      double    gammastddev;
    }                   inputs;
  double                dgamma[5*5];
};

static void
test_dqfuncdgamma (void)
{
  DqfuncDgammaTestDatum data[] = 
    {{{{0, 0.225711, 0.954541, 0.726477, 0.0208239, 0.601365, 0, 0.528873,  0.161277, 0.707536, 0.818486, 0.901529, 0, 0.00613998, 0.19505,  0.750215, 0.0263554, 0.315146, 0, 0.0450285, 0.815193, 0.365411,  0.326712, 0.930906, 0, 0, 0.238115, 0.468015, 0.725214, 0.385872,  0.012404, 0, 0.513475, 0.998737, 0.365049, 0.411039, 0.984601, 0,  0.83746, 0.657513, 0.592554, 0.0830725, 0.83132, 0, 0.462463,  0.842339, 0.056717, 0.516174, 0.417434, 0, 0, 0.0271455, 0.691306,  0.189462, 0.486528, 0.789031, 0, 0.223291, 0.464248, 0.100656,  0.776627, 0.709816, 0, 0.465511, 0.735607, 0.365587, 0.725215,  0.628051, 0, 0.0780945, 0.773034, 0.642142, 0.796731, 0.615632, 0,  0, 0.930695, 0.585425, 0.280557, 0.198197, 0.90355, 0, 0.894119,  0.0910955, 0.711669, 0.114519, 0.670829, 0, 0.626848, 0.611013,  0.337892, 0.961013, 0.161337, 0, 0.875406, 0.972304, 0.235798,  0.533286, 0.797311, 0}, {0.199271, 0.593656, 0.736554}, {1.,  0.181679, 0.268576, 0.00823119, 0.455997, 0.983482, 1., 0.365026,  0.114112, 0.364902, 0.271814, 0.250507, 1., 0.443283, 0.738054,  0.660801, 0.912616, 0.48227, 1., 0.576717, 0.785395, 0.940311,  0.246471, 0.0434309, 1.}, {0.988084, 0.74104, 0.652815, 0.306877,  0.806405, 0.472465, 0.644584, 0.85088, 0.822922, 0.107439,  0.530472, 0.485978, 0.551109, 0.856931, 0.0871894}, {0.747924,  0.890308, 0.944316, 0.60492,  0.171208}, {{3, 1, 0}, {1, 2, 1}, {2, 2, 4}, {1, 2, 4}, {0, 0,  0}, {3, 2, 2}, {2, 0, 4}, {0, 2, 3}}, 0.104913, 0.00400454,  0.358448, 0.127777, 0.116828}, {-427.321, 59.1898, 137.321,  180.363, -90.604, -210.566, -427.321, 46.1841, 115.378, 21.2671,  83.3369,  196.77, -427.321, -8.32242, -113.129, -93.2885, -226.019, -25.3569, -427.321, -109.743, -24.4417, -283.139, 99.1494,  241.27, -427.321}}, {{{0, 0.262964, 0.705633, 0.8209, 0.310424,  0.790499, 0, 0.0610495, 0.970021, 0.487502, 0.683061, 0.530577, 0,  0.484042, 0.936393, 0.82613, 0.443388, 0.736118, 0, 0.0460853,  0.881814, 0.838468, 0.56491, 0.941173, 0, 0, 0.877809, 0.48002,  0.437134, 0.824344, 0.614845, 0, 0.774387, 0.616234, 0.51392,  0.824346, 0.713337, 0, 0.646213, 0.0264187, 0.141285, 0.18276,  0.162171, 0, 0.0900256, 0.315156, 0.739372, 0.426052, 0.0439403,  0, 0, 0.433342, 0.900903, 0.861142, 0.102768, 0.555532, 0,  0.420883, 0.424008, 0.278424, 0.940687, 0.646497, 0, 0.807775,  0.764503, 0.116341, 0.93316, 0.161562, 0, 0.738085, 0.975056,  0.7504, 0.999391, 0.648059, 0, 0, 0.6599, 0.0110282, 0.573339,  0.604119, 0.226558, 0, 0.110125, 0.712197, 0.501351, 0.671026,  0.689241, 0, 0.288188, 0.222927, 0.730339, 0.0427448, 0.480413, 0,  0.458424, 0.613997, 0.109585, 0.318852, 0.72034, 0}, {0.638941,  0.359185, 0.31946}, {1., 0.0722806, 0.979041, 0.348157, 0.746122,  0.468162, 1., 0.752483, 0.238032, 0.0339252, 0.966811, 0.0814566,  1., 0.548791, 0.745737, 0.743884, 0.351118, 0.506046, 1.,  0.265324, 0.285459, 0.737121, 0.396461, 0.946472, 1.}, {0.56512,  0.0981791, 0.0372756, 0.627012, 0.492839, 0.119138, 0.689118,  0.88089, 0.0246773, 0.366655, 0.451086, 0.846965, 0.0578663,  0.285199, 0.902295}, {0.101228, 0.313983, 0.934081, 0.396249,  0.835904}, {{0, 2, 2}, {1, 2, 1}, {3, 0, 2}, {2, 0, 1}, {3, 0,  2}, {3, 0, 3}, {0, 2, 3}, {0, 1, 2}}, 0.0285231, 0.19696,  0.999788, 0.889432, 0.463403}, {-4917.12, 2394.37, -2235.73,  1600.28, -1404.05, 388.883, -4917.12, -2019.46, 2179.04,  2026.55, -919.918, 2774.06, -4917.12, 39.757, -1268.68, -1426.91,  245.363, -593.026, -4917.12, 336.404, 2023.77, -626.968,  891.416, -1760.87, -4917.12}}, {{{0, 0.0987813, 0.962513, 0.26242,  0.970564, 0.979643, 0, 0.273394, 0.38153, 0.945887, 0.612988,  0.822308, 0, 0.534566, 0.88802, 0.327789, 0.920013, 0.433338, 0,  0.574038, 0.393708, 0.523763, 0.597434, 0.545515, 0, 0, 0.196748,  0.523975, 0.708002, 0.0821113, 0.0979663, 0, 0.561462, 0.445582,  0.111547, 0.118323, 0.288068, 0, 0.0640518, 0.165661, 0.505335,  0.46576, 0.529486, 0, 0.27764, 0.177547, 0.545747, 0.0961481,  0.703603, 0, 0, 0.783839, 0.0219835, 0.498714, 0.158088, 0.587091,  0, 0.498009, 0.790712, 0.0759768, 0.489125, 0.936546, 0, 0.34513,  0.964429, 0.370802, 0.648479, 0.281078, 0, 0.798769, 0.865466,  0.182719, 0.751592, 0.521128, 0, 0, 0.68792, 0.636972, 0.655444,  0.817526, 0.904081, 0, 0.614989, 0.15673, 0.659437, 0.31699,  0.11698, 0, 0.366018, 0.583461, 0.827865, 0.180434, 0.0208881, 0,  0.619031, 0.457063, 0.531955, 0.73981, 0.820263, 0}, {0.591597,  0.349236, 0.988219}, {1., 0.299134, 0.903678, 0.712264, 0.332775,  0.481609, 1., 0.999597, 0.0972756, 0.176046, 0.822171, 0.682607,  1., 0.980296, 0.810028, 0.238711, 0.854741, 0.799862, 1., 0.78914,  0.61968, 0.397678, 0.267907, 0.0493294, 1.}, {0.799417, 0.806081,  0.918671, 0.0611108, 0.500283, 0.902403, 0.206406, 0.728336,  0.0186738, 0.902807, 0.109131, 0.55229, 0.196502, 0.2202,  0.128835}, {0.742262, 0.957792, 0.365459, 0.328973,  0.953122}, {{3, 2, 1}, {2, 0, 2}, {0, 2, 3}, {2, 1, 1}, {1, 2,  0}, {1, 0, 0}, {2, 0, 2}, {0, 1, 3}}, 0.338112, 0.967781,  0.0610667, 0.903793, 0.538695}, {-35.3211,  7.07624, -12.8519, -5.67727, 8.06631, 7.07369, -35.3211, -18.267,  14.8983, 12.0308, -15.0377, -4.19342, -35.3211, -23.1067, -5.26246,  11.7123, -10.3653, -16.5651, -35.3211, -7.36457, -4.13761,  3.43645, 11.9302,  23.8787, -35.3211}}, {{{0, 0.1617, 0.142396, 0.842682, 0.0384124,  0.259297, 0, 0.93599, 0.114347, 0.0197387, 0.35649, 0.826859, 0,  0.562057, 0.823236, 0.13629, 0.698024, 0.819794, 0, 0.865445,  0.770832, 0.36905, 0.866672, 0.527333, 0, 0, 0.803051, 0.307984,  0.962879, 0.988638, 0.641351, 0, 0.165587, 0.120197, 0.950225,  0.382054, 0.229598, 0, 0.00585039, 0.930487, 0.0255639, 0.402738,  0.443794, 0, 0.10725, 0.889274, 0.704715, 0.623999, 0.241806, 0,  0, 0.118442, 0.335664, 0.757327, 0.714473, 0.315391, 0, 0.0276807,  0.794448, 0.725835, 0.674039, 0.862093, 0, 0.674251, 0.77561,  0.291985, 0.632496, 0.668401, 0, 0.845123, 0.266421, 0.229757,  0.224607, 0.737873, 0, 0, 0.377148, 0.525043, 0.600608, 0.496067,  0.258706, 0, 0.189378, 0.84328, 0.781595, 0.943315, 0.161698, 0,  0.0488323, 0.0557595, 0.269276, 0.299604, 0.374581, 0, 0.28015,  0.977291, 0.667108, 0.706181, 0.435027, 0}, {0.71087, 0.437351,  0.481574}, {1., 0.697154, 0.333722, 0.912309, 0.880966, 0.201087,  1., 0.0750162, 0.72293, 0.0376858, 0.419492, 0.131701, 1.,  0.561233, 0.988853, 0.363732, 0.862425, 0.261628, 1., 0.614272,  0.0835827, 0.885134, 0.59452, 0.908092, 1.}, {0.648556, 0.174264,  0.157169, 0.426518, 0.951402, 0.840542, 0.24486, 0.545552,  0.750316, 0.765526, 0.52193, 0.507866, 0.330824, 0.633825,  0.960697}, {0.519012, 0.967091, 0.7714, 0.699069,  0.90474}, {{3, 2, 3}, {3, 1, 0}, {0, 0, 3}, {1, 0, 0}, {3, 2,  2}, {1, 2, 3}, {2, 1, 0}, {2, 1, 2}}, 0.883509, 0.886266,  0.104549, 0.996649, 0.234952}, {-5.18506, 3.72373, 11.9785,  0.905545, 0.447773, 15.2705, -5.18506, 18.0003, 3.65243, 20.3523,  11.3237, 17.6587, -5.18506, 6.66551, -1.61428, 10.5278, 0.616381,  14.9292, -5.18506, 6.46672, 19.832, 0.00891288,  7.34016, -0.561248, -5.18506}}, {{{0, 0.712002, 0.94738, 0.570131,  0.28355, 0.871459, 0, 0.70252, 0.0245791, 0.533234, 0.105933,  0.18059, 0, 0.516713, 0.202411, 0.472108, 0.219892, 0.997701, 0,  0.235319, 0.700708, 0.520823, 0.0929604, 0.351811, 0, 0, 0.814442,  0.416275, 0.0963117, 0.116858, 0.10244, 0, 0.468895, 0.526181,  0.833308, 0.230981, 0.766375, 0, 0.501602, 0.300074, 0.125048,  0.585785, 0.984888, 0, 0.0976632, 0.65294, 0.365893, 0.987188,  0.862344, 0, 0, 0.952232, 0.845069, 0.894227, 0.510533, 0.13779,  0, 0.428795, 0.797916, 0.393675, 0.0353492, 0.9599, 0, 0.271735,  0.560367, 0.804368, 0.193525, 0.770133, 0, 0.260293, 0.67932,  0.60774, 0.785245, 0.16263, 0, 0, 0.0263809, 0.241847, 0.798057,  0.300286, 0.0741493, 0, 0.396778, 0.90383, 0.789753, 0.93636,  0.967984, 0, 0.105914, 0.396078, 0.90101, 0.00808355, 0.834179, 0,  0.835711, 0.0966423, 0.814558, 0.0640461, 0.575418,  0}, {0.417322, 0.206818, 0.278802}, {1., 0.412788, 0.390941,  0.964971, 0.480745, 0.112502, 1., 0.316792, 0.568193, 0.576915,  0.32275, 0.380432, 1., 0.600209, 0.471001, 0.926672, 0.479422,  0.592125, 1., 0.636822, 0.0909613, 0.382779, 0.777567, 0.572776,  1.}, {0.515543, 0.965457, 0.570749, 0.293974, 0.102755, 0.574516,  0.605778, 0.81323, 0.990253, 0.257725, 0.0375856, 0.236315,  0.667503, 0.877293, 0.437377}, {0.765313, 0.740831, 0.397871,  0.845251,  0.128491}, {{2, 2, 0}, {2, 0, 0}, {1, 1, 3}, {2, 0, 2}, {3, 2,  2}, {2, 2, 1}, {0, 0, 4}, {0, 0, 3}}, 0.64987, 0.0150919,  0.0676843, 0.555715, 0.134326}, {-34.0941, 9.94311,  11.2318, -26.236, 2.46966, 26.3058, -34.0941,  14.9695, -0.739517, -0.60117, 12.953, 12.9184, -34.0941, -4.84525,  3.68848, -23.8837, 2.07262, 0.867073, -34.0941, -7.14297, 29.9383,  11.4263, -15.0913, -1.74798, -34.0941}}, {{{0, 0.0496345, 0.496935,  0.261741, 0.0315712, 0.475118, 0, 0.891157, 0.448511, 0.0413182,  0.217393, 0.853572, 0, 0.212197, 0.373815, 0.340101, 0.416195,  0.446884, 0, 0.632984, 0.94223, 0.570944, 0.318392, 0.983114, 0,  0, 0.927138, 0.503259, 0.762677, 0.848788, 0.877503, 0,  0.00632393, 0.500936, 0.817216, 0.402385, 0.115167, 0, 0.0524247,  0.775898, 0.184992, 0.261595, 0.840228, 0, 0.402083, 0.844891,  0.8454, 0.393344, 0.769099, 0, 0, 0.902661, 0.274457, 0.0749521,  0.785985, 0.975524, 0, 0.771197, 0.312275, 0.937198, 0.0980207,  0.764873, 0, 0.811339, 0.119981, 0.695636, 0.649707, 0.758915, 0,  0.344083, 0.510644, 0.388112, 0.918687, 0.942, 0, 0, 0.665753,  0.542711, 0.525342, 0.1729, 0.763092, 0, 0.268255, 0.45039,  0.386915, 0.787568, 0.497057, 0, 0.138115, 0.449717, 0.689547,  0.732184, 0.326776, 0, 0.329736, 0.993912, 0.0824775, 0.567861,  0.985653, 0}, {0.483267, 0.694366, 0.649175}, {1., 0.0436537,  0.817514, 0.151655, 0.123832, 0.870754, 1., 0.0544224, 0.8834,  0.673442, 0.483839, 0.266854, 1., 0.386342, 0.535327, 0.0341214,  0.577307, 0.654158, 1., 0.208551, 0.704385, 0.583395, 0.571681,  0.64069, 1.}, {0.718732, 0.100128, 0.877315, 0.991516, 0.675078,  0.282614, 0.72566, 0.867683, 0.804325, 0.228192, 0.84226,  0.194241, 0.320486, 0.961337, 0.455918}, {0.658914, 0.286365,  0.38403, 0.80176,  0.450362}, {{2, 1, 4}, {3, 2, 2}, {2, 2, 4}, {3, 1, 2}, {3, 1,  2}, {1, 2, 4}, {1, 0, 1}, {0, 0, 4}}, 0.581979, 0.800635,  0.230079, 0.809672, 0.863247}, {-12.0653, 8.02697, -4.29955,  3.88889, 4.88822, -1.23868, -12.0653,  6.0895, -5.47682, -1.32626, -0.832283,  4.16289, -12.0653, -0.410051, -0.877483,  6.27779, -0.424962, -0.511212, -12.0653, 3.38913,  1.54116, -1.01506, 0.0582525,  3.52498, -12.0653}}, {{{0, 0.700507, 0.352765, 0.818156, 0.188169,  0.417893, 0, 0.627104, 0.950473, 0.383845, 0.189701, 0.784844, 0,  0.756232, 0.0633587, 0.228364, 0.328926, 0.0973184, 0, 0.776994,  0.844334, 0.527166, 0.646956, 0.195015, 0, 0, 0.0436992, 0.297086,  0.837284, 0.331767, 0.343193, 0, 0.944322, 0.0191277, 0.143598,  0.9253, 0.317217, 0, 0.0686545, 0.759754, 0.735598, 0.532374,  0.312422, 0, 0.696395, 0.507234, 0.203448, 0.215104, 0.919401, 0,  0, 0.662901, 0.676282, 0.568148, 0.724386, 0.619201, 0, 0.379195,  0.730864, 0.392619, 0.276009, 0.434874, 0, 0.711736, 0.249021,  0.350709, 0.117656, 0.643082, 0, 0.489267, 0.61511, 0.585283,  0.330659, 0.792872, 0, 0, 0.107876, 0.381835, 0.115555, 0.873471,  0.444976, 0, 0.705553, 0.547407, 0.149085, 0.825774, 0.326357, 0,  0.816543, 0.756467, 0.549766, 0.891484, 0.104807, 0, 0.507446,  0.199057, 0.773828, 0.461725, 0.0181791, 0}, {0.583946, 0.188545,  0.131066}, {1., 0.225307, 0.47607, 0.80671, 0.015511, 0.351835,  1., 0.0310944, 0.101157, 0.468104, 0.20275, 0.20532, 1., 0.7748,  0.65156, 0.446283, 0.655555, 0.883316, 1., 0.546753, 0.938837,  0.456498, 0.109488, 0.0850281, 1.}, {0.920658, 0.872552, 0.920943,  0.953962, 0.695351, 0.396482, 0.114233, 0.938451, 0.343516,  0.365388, 0.0130754, 0.470347, 0.140766, 0.160067,  0.238275}, {0.818787, 0.694482, 0.504513, 0.354959,  0.272033}, {{1, 2, 1}, {1, 1, 1}, {0, 1, 4}, {1, 1, 1}, {1, 1,  3}, {3, 0, 4}, {1, 1, 1}, {1, 2, 0}}, 0.755645, 0.0480148,  0.245471, 0.187005, 0.834987}, {-8.17134,  1.01994, -0.75841, -2.44348, 3.84624, 0.495497, -8.17134, 4.6576,  3.35123, -1.80996, 2.43939,  1.79862, -8.17134, -2.14961, -2.0282, -0.232994, -1.98865, -5.1592, -8.17134, -0.0202071, -3.86226, 0.0753434, 2.24164,  2.92272, -8.17134}}, {{{0, 0.175463, 0.324528, 0.233043, 0.139636,  0.778981, 0, 0.210295, 0.294592, 0.79612, 0.413593, 0.197219, 0,  0.824245, 0.655354, 0.253526, 0.958944, 0.00545822, 0, 0.960872,  0.749013, 0.603985, 0.733425, 0.205226, 0, 0, 0.700998, 0.358514,  0.54642, 0.370239, 0.525535, 0, 0.0339865, 0.313376, 0.230604,  0.746555, 0.823692, 0, 0.0187843, 0.434484, 0.332961, 0.626472,  0.194539, 0, 0.779129, 0.0794356, 0.667528, 0.189081, 0.818258, 0,  0, 0.330423, 0.0635434, 0.455656, 0.613031, 0.629425, 0,  0.705029, 0.909236, 0.242792, 0.103889, 0.671043, 0, 0.59586,  0.0121886, 0.357335, 0.847351, 0.577076, 0, 0.577705, 0.0243734,  0.220879, 0.382536, 0.798576, 0, 0, 0.944938, 0.55335, 0.193455,  0.980318, 0.614515, 0, 0.489807, 0.737799, 0.367286, 0.98509,  0.784778, 0, 0.828563, 0.124494, 0.881201, 0.113735, 0.232703, 0,  0.112306, 0.523866, 0.266384, 0.655627, 0.5346, 0}, {0.499493,  0.045505, 0.273091}, {1., 0.736025, 0.554555, 0.492155, 0.0796354,  0.755707, 1., 0.94004, 0.00234763, 0.341836, 0.388421, 0.95495,  1., 0.21757, 0.513273, 0.263927, 0.0737485, 0.103835, 1.,  0.280571, 0.151621, 0.549882, 0.837452, 0.624944, 1.}, {0.617021,  0.0503892, 0.791947, 0.351853, 0.880996, 0.495834, 0.299792,  0.272218, 0.125289, 0.555794, 0.297444, 0.930381, 0.736868,  0.600844, 0.0798743}, {0.417108, 0.472941, 0.527096, 0.976039,  0.136537}, {{3, 1, 2}, {0, 2, 3}, {3, 2, 1}, {0, 2, 2}, {3, 1,  0}, {0, 1, 0}, {3, 2, 2}, {2, 0, 0}}, 0.32132, 0.977214,  0.138588, 0.511594,  0.7043}, {-39.7268, -8.12609, -8.98069, -5.19144,  18.1564, -5.08668, -39.7268, -23.3443, 22.7766, 2.95207,  6.98406, -13.9021, -39.7268, 14.1251, -8.00917, 7.95052, 22.6898,  6.57946, -39.7268, 13.1318,  8.18554, -4.34611, -14.1115, -1.61466, -39.7268}}, {{{0, 0.926825,  0.346641, 0.159741, 0.823304, 0.430991, 0, 0.046849, 0.887523,  0.698015, 0.875197, 0.749405, 0, 0.957142, 0.961147, 0.274352,  0.66953, 0.540034, 0, 0.488206, 0.747256, 0.693491, 0.403497,  0.166886, 0, 0, 0.770042, 0.554904, 0.891903, 0.462586, 0.843217,  0, 0.208263, 0.732162, 0.639282, 0.412227, 0.161414, 0, 0.844639,  0.941267, 0.53703, 0.412009, 0.887497, 0, 0.98012, 0.262678,  0.742479, 0.347463, 0.491914, 0, 0, 0.515422, 0.0489877, 0.943967,  0.325028, 0.74538, 0, 0.494084, 0.0520635, 0.862442, 0.902163,  0.285821, 0, 0.319901, 0.22316, 0.489936, 0.124408, 0.475262, 0,  0.281893, 0.952906, 0.712399, 0.587765, 0.301774, 0, 0, 0.690228,  0.96992, 0.240302, 0.80986, 0.174806, 0, 0.920932, 0.296336,  0.484832, 0.429426, 0.426848, 0, 0.244272, 0.622389, 0.527263,  0.141027, 0.924371, 0, 0.399229, 0.0373273, 0.0166191, 0.449108,  0.117336, 0}, {0.0844215, 0.304221, 0.861343}, {1., 0.815562,  0.394194, 0.334301, 0.621041, 0.00570167, 1., 0.219388, 0.413369,  0.324706, 0.52087, 0.789962, 1., 0.986521, 0.0804335, 0.898481,  0.262699, 0.845494, 1., 0.156063, 0.499252, 0.225372, 0.828875,  0.706954, 1.}, {0.381916, 0.14095, 0.524655, 0.845611, 0.566354,  0.746757, 0.190354, 0.22457, 0.560653, 0.527369, 0.776985,  0.899865, 0.0397828, 0.737406, 0.790464}, {0.819431, 0.141302,  0.474707, 0.94497,  0.663368}, {{0, 0, 4}, {3, 2, 0}, {0, 1, 4}, {3, 1, 3}, {3, 1,  0}, {1, 2, 1}, {2, 2, 3}, {2, 1, 3}}, 0.642051, 0.249336,  0.116095, 0.956414, 0.260135}, {-10.3474, 1.2088, 9.14196, 11.3735,  4.80224, 19.3172, -10.3474, 12.8141, 8.78809, 12.6967,  7.73541, -1.2672, -10.3474, -4.27805, 18.8305, -3.42632, 10.9699,  0.293248, -10.3474, 15.5271, 6.76342,  13.8681, -1.82115, -0.558569, -10.3474}}, {{{0, 0.108385, 0.59144,  0.110803, 0.69378, 0.361629, 0, 0.401086, 0.886232, 0.133127,  0.83426, 0.624102, 0, 0.986368, 0.0933447, 0.0968538, 0.833638,  0.166936, 0, 0.952042, 0.622146, 0.888668, 0.503568, 0.309992, 0,  0, 0.372811, 0.772573, 0.547154, 0.0498573, 0.264425, 0, 0.181133,  0.436351, 0.356077, 0.902797, 0.780047, 0, 0.550119, 0.22295,  0.0685363, 0.155945, 0.563752, 0, 0.129605, 0.971682, 0.322307,  0.396815, 0.177563, 0, 0, 0.349536, 0.433639, 0.893247, 0.867571,  0.976725, 0, 0.661066, 0.346094, 0.817713, 0.7123, 0.479933, 0,  0.909742, 0.461636, 0.809503, 0.699886, 0.359623, 0, 0.238686,  0.740967, 0.543941, 0.795871, 0.109081, 0, 0, 0.769285, 0.221634,  0.399056, 0.931519, 0.419749, 0, 0.787995, 0.505809, 0.0639483,  0.443023, 0.126928, 0, 0.159715, 0.246235, 0.730723, 0.646995,  0.249973, 0, 0.784599, 0.92122, 0.947109, 0.89035, 0.545912,  0}, {0.180253, 0.403167, 0.0944784}, {1., 0.436831, 0.410968,  0.181533, 0.695422, 0.505312, 1., 0.99122, 0.393539, 0.189614,  0.441364, 0.548196, 1., 0.26661, 0.0298985, 0.195129, 0.817473,  0.619615, 1., 0.779926, 0.41053, 0.896253, 0.672506, 0.889576,  1.}, {0.864618, 0.716, 0.269339, 0.795097, 0.427787, 0.305032,  0.0878054, 0.0996749, 0.922475, 0.313812, 0.694267, 0.910061,  0.481112, 0.765616, 0.427657}, {0.880163, 0.285983, 0.948143,  0.808042,  0.100237}, {{3, 1, 0}, {2, 2, 0}, {2, 2, 2}, {3, 0, 3}, {2, 0,  1}, {2, 2, 4}, {2, 1, 3}, {1, 1, 3}}, 0.875453, 0.0518897,  0.135536, 0.210662, 0.0108352}, {-6728.62, -1926.65, -1705.67,  249.708, -4129.39, -2509.76, -6728.62, -6651.14, -1556.92,  180.078, -1963.6, -2875.28, -6728.62, -474.547, 1540.88,  133.51, -5169.89, -3484.85, -6728.62, -4850.18, -1700.33, -5840.86, -3934.02, -5785.98, -6728.62}}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      double dalpha[4*5*5];
      double dlogbeta[3];
      double dgamma[5*5];
      ParameterizedNormalDistribution prior_alpha = 
        parameterized_normal_distribution (data[i].inputs.alphastddev);
      NormalDistribution prior_logbeta = 
        normal_distribution (data[i].inputs.logbetamean, 
                             data[i].inputs.logbetastddev);
      NormalDistribution prior_gamma = 
        normal_distribution (data[i].inputs.gammamean, 
                             data[i].inputs.gammastddev);

      memset (dalpha, lrand48 (), 4*5*5 * sizeof (dalpha[0]));

      for (unsigned int j = 0; j < 4; ++j)
        {
          for (unsigned int k = 0; k < 5; ++k)
            {
              data[i].inputs.alpha[j * 5 * 5 + k * 5 + k] = drand48 ();
            }
        }

      for (unsigned int k = 0; k < 5; ++k)
        {
          data[i].inputs.gamma[k * 5 + k] = drand48 ();
        }

      dqfunc (dalpha,
              dlogbeta,
              dgamma,
              data[i].inputs.alpha,
              4,
              5,
              data[i].inputs.logbeta,
              3,
              data[i].inputs.gamma,
              data[i].inputs.pz,
              data[i].inputs.ratings,
              8,
              &prior_alpha.base,
              &prior_logbeta.base,
              &prior_gamma.base,
              0);

      for (unsigned int j = 0; j < 5*5; ++j)
        {
          if (j % 5 == (j / 5) % 5)
            {
              assert (dgamma[j] == 0.0 || 
                      (fprintf (stderr, "%u %u: %g ?= 0\n", i, j, dgamma[j]), 
                       0));
            }
          else
            {
              assert (fabs (dgamma[j] - data[i].dgamma[j]) <=
                      5e-5 * (1 + fabs (dgamma[j]) + fabs (data[i].dgamma[j])) ||
                      (fprintf (stderr, "%u %u: %g ?= %g\n", i, j, dgamma[j], data[i].dgamma[j]),
                       0));
            }
        }
    }
}

static void
test_dqfuncdgamma_symmetric (void)
{
  DqfuncDgammaTestDatum data[] = 
    {{{{0, 0.33589, 0.866197, 0.415564, 0.583048, 0.0308576, 0, 0.778392,  0.315889, 0.660573, 0.717045, 0.0841251, 0, 0.405828, 0.179462,  0.95143, 0.656468, 0.525665, 0, 0.893479, 0.00328683, 0.848427,  0.425428, 0.0180259, 0, 0, 0.951397, 0.712891, 0.214766,  0.00719065, 0.615508, 0, 0.846693, 0.799202, 0.424142, 0.58465,  0.0683016, 0, 0.483313, 0.763569, 0.867605, 0.984176, 0.0774845,  0, 0.584108, 0.916175, 0.327708, 0.551819, 0.690629, 0, 0,  0.912888, 0.479281, 0.126391, 0.672603, 0.961491, 0, 0.766391,  0.911625, 0.665412, 0.345983, 0.919697, 0, 0.112422, 0.24127,  0.761333, 0.851395, 0.62911, 0, 0.477701, 0.893729, 0.867219,  0.551625, 0.893593, 0, 0, 0.977554, 0.539511, 0.999806, 0.202964,  0.0646658, 0, 0.0602299, 0.873415, 0.530361, 0.103175, 0.293839,  0, 0.96179, 0.864949, 0.757191, 0.374142, 0.849368, 0, 0.623679,  0.995858, 0.522747, 0.220258, 0.145978, 0}, {0.102129, 0.655528,  0.668633}, {1., 0.252385, 0.124575, 0.116017, 0.668827, 0.0494211,  1., 0.0599093, 0.0557868, 0.795412, 0.51906, 0.956735, 1.,  0.761947, 0.833621, 0.654111, 0.199543, 0.387805, 1., 0.984253,  0.0304316, 0.203685, 0.865058, 0.763995, 1.}, {0.884453, 0.101556,  0.20953, 0.0953625, 0.632068, 0.976981, 0.0935137, 0.426536,  0.582647, 0.917072, 0.0377269, 0.631124, 0.0635871, 0.960337,  0.275779}, {0.797503, 0.409476, 0.760794, 0.887974,  0.813249}, {{0, 2, 1}, {0, 0, 4}, {2, 2, 3}, {3, 1, 4}, {0, 2,  4}, {2, 1, 1}, {2, 0, 4}, {2, 1, 2}}, 0.379045, 0.557109,  0.0229163, 0.0492539, 0.494592}, {-31.7272, 28.5211, 28.611,  17.4456, -21.9022, 28.5211, -31.7272, 30.7056, 37.211, -18.6449,  28.611, 30.7056, -31.7272, -20.9226, -24.3038, 17.4456,  37.211, -20.9226, -31.7272, -26.5489, -21.9022, -18.6449, -24.3038, -26.5489, -31.7272}}, {{{0, 0.455552, 0.813386, 0.953891,  0.862524, 0.478571, 0, 0.719872, 0.527356, 0.279877, 0.561499,  0.682145, 0, 0.896232, 0.21629, 0.601162, 0.406366, 0.0987289, 0,  0.806814, 0.840368, 0.518391, 0.28548, 0.427769, 0, 0, 0.283259,  0.495475, 0.236226, 0.933177, 0.827707, 0, 0.682089, 0.282334,  0.0706535, 0.349136, 0.962217, 0, 0.754979, 0.790777, 0.787636,  0.280072, 0.858747, 0, 0.574487, 0.186474, 0.873706, 0.760018,  0.767673, 0, 0, 0.346106, 0.355314, 0.474539, 0.339904, 0.0628471,  0, 0.859839, 0.238313, 0.406727, 0.23514, 0.17775, 0, 0.955978,  0.336074, 0.886004, 0.215533, 0.201, 0, 0.545297, 0.0983679,  0.935461, 0.342252, 0.97081, 0, 0, 0.911894, 0.0617556, 0.582234,  0.203137, 0.565787, 0, 0.706441, 0.107696, 0.863233, 0.50294,  0.846602, 0, 0.869383, 0.456506, 0.2678, 0.668852, 0.913404, 0,  0.120432, 0.381796, 0.453318, 0.712404, 0.575135, 0}, {0.283428,  0.517857, 0.370152}, {1., 0.604325, 0.371534, 0.456101, 0.787918,  0.401187, 1., 0.805747, 0.74966, 0.680222, 0.537955, 0.302807, 1.,  0.903059, 0.81084, 0.081449, 0.0350069, 0.234207, 1., 0.897436,  0.961017, 0.653211, 0.780888, 0.185031, 1.}, {0.385882, 0.369784,  0.263031, 0.814879, 0.781557, 0.998249, 0.80693, 0.0269613,  0.38037, 0.192502, 0.0572697, 0.346739, 0.842415, 0.889695,  0.154211}, {0.535899, 0.760966, 0.854688, 0.920004,  0.638464}, {{0, 0, 4}, {3, 1, 1}, {1, 0, 2}, {1, 2, 2}, {0, 1,  3}, {2, 2, 2}, {2, 2, 1}, {0, 0, 1}}, 0.799949, 0.201477,  0.139116, 0.453433, 0.414067}, {-9.43867, -3.07437, 1.70481,  1.28931, -6.44253, -3.07437, -9.43867, -4.90596, -9.21544, -6.0847,  1.70481, -4.90596, -9.43867, -5.66894, -8.68137,  1.28931, -9.21544, -5.66894, -9.43867, -10.0009, -6.44253, -6.0847, -8.68137, -10.0009, -9.43867}}, {{{0, 0.831694, 0.876084,  0.638553, 0.63251, 0.833444, 0, 0.0691543, 0.611592, 0.25214,  0.640942, 0.0118846, 0, 0.264853, 0.409725, 0.751246, 0.857673,  0.728954, 0, 0.648759, 0.896558, 0.937669, 0.0904903, 0.848809, 0,  0, 0.695081, 0.798554, 0.637058, 0.434742, 0.863387, 0, 0.922469,  0.998504, 0.802232, 0.029943, 0.853315, 0, 0.386912, 0.550092,  0.389001, 0.84143, 0.122059, 0, 0.140367, 0.637755, 0.983757,  0.393105, 0.491609, 0, 0, 0.741197, 0.0460877, 0.302615, 0.642799,  0.0461162, 0, 0.247534, 0.665557, 0.208057, 0.182729, 0.325065,  0, 0.667053, 0.405825, 0.152786, 0.47175, 0.280141, 0, 0.855733,  0.763785, 0.630319, 0.158082, 0.715365, 0, 0, 0.12603, 0.646563,  0.764977, 0.223757, 0.384833, 0, 0.600475, 0.462362, 0.580957,  0.338717, 0.352941, 0, 0.796806, 0.3729, 0.155988, 0.0278759,  0.129753, 0, 0.967075, 0.00320201, 0.556126, 0.849612, 0.111342,  0}, {0.239417, 0.925807, 0.691531}, {1., 0.395976, 0.113387,  0.279244, 0.926554, 0.17222, 1., 0.728554, 0.678769, 0.464191,  0.591263, 0.389837, 1., 0.325828, 0.667386, 0.218363, 0.233849,  0.297953, 1., 0.537633, 0.251288, 0.230647, 0.741827, 0.68802,  1.}, {0.139946, 0.99123, 0.81602, 0.99649, 0.74397, 0.877843,  0.536776, 0.0699357, 0.57175, 0.149289, 0.858007, 0.605744,  0.980487, 0.759452, 0.532178}, {0.938359, 0.762124, 0.525603,  0.234226,  0.400726}, {{3, 0, 2}, {2, 0, 4}, {0, 0, 3}, {2, 2, 0}, {3, 1,  4}, {0, 1, 1}, {2, 1, 1}, {2, 2, 1}}, 0.510836, 0.294956,  0.492399, 0.712706, 0.37089}, {-17.4169, 10.8137, 23.3809,  15.7002, -16.6933, 10.8137, -17.4169, -8.46625, 0.669225, 3.51068,  23.3809, -8.46625, -17.4169, 11.8506, -6.47648, 15.7002, 0.669225,  11.8506, -17.4169, 6.08169, -16.6933, 3.51068, -6.47648,  6.08169, -17.4169}}, {{{0, 0.303727, 0.676379, 0.716216, 0.62692,  0.425884, 0, 0.139603, 0.64628, 0.0551696, 0.276595, 0.281596, 0,  0.0405359, 0.0746823, 0.517144, 0.749418, 0.102177, 0, 0.312558,  0.99154, 0.515192, 0.701451, 0.801722, 0, 0, 0.696584, 0.0227931,  0.988746, 0.430832, 0.392857, 0, 0.346414, 0.27253, 0.803913,  0.966973, 0.206811, 0, 0.62625, 0.748743, 0.690378, 0.925215,  0.585714, 0, 0.674061, 0.173234, 0.175797, 0.483536, 0.361503, 0,  0, 0.181694, 0.660605, 0.782085, 0.559781, 0.48511, 0, 0.637812,  0.793339, 0.128949, 0.0922524, 0.291398, 0, 0.520809, 0.325036,  0.125279, 0.0845867, 0.89456, 0, 0.576293, 0.434902, 0.159372,  0.308846, 0.902232, 0, 0, 0.261668, 0.983575, 0.82531, 0.540729,  0.079974, 0, 0.32297, 0.0432247, 0.980948, 0.594864, 0.685159, 0,  0.249886, 0.851999, 0.502612, 0.393761, 0.729077, 0, 0.526964,  0.377333, 0.309174, 0.834517, 0.950671, 0}, {0.942431, 0.149802,  0.525671}, {1., 0.0484389, 0.680763, 0.166227, 0.700362, 0.50771,  1., 0.600789, 0.843257, 0.657137, 0.526762, 0.00592502, 1.,  0.158098, 0.407251, 0.674762, 0.503313, 0.764338, 1., 0.678174,  0.147799, 0.12598, 0.455163, 0.843657, 1.}, {0.197128, 0.183549,  0.305361, 0.317986, 0.148689, 0.502786, 0.139134, 0.617624,  0.640979, 0.901996, 0.295876, 0.960487, 0.114217, 0.896071,  0.137778}, {0.553236, 0.439455, 0.392758, 0.37344,  0.875062}, {{2, 1, 4}, {3, 0, 1}, {1, 1, 3}, {2, 0, 1}, {3, 2,  2}, {0, 1, 2}, {2, 0, 4}, {0, 0, 2}}, 0.291656, 0.266778,  0.918277, 0.0314042, 0.0945281}, {-155.422, 25.5751, -154.27,  32.0698, -164.852,  25.5751, -155.422, -149.928, -219.747, -155.562, -154.27, -149.928, -155.422, -9.42806, -75.3902,  32.0698, -219.747, -9.42806, -155.422, -159.407, -164.852, -155.562, -75.3902, -159.407, -155.422}}, {{{0, 0.0832289, 0.612916,  0.713418, 0.945839, 0.580443, 0, 0.473783, 0.095794, 0.30486,  0.678447, 0.177906, 0, 0.135307, 0.190642, 0.782376, 0.0401283,  0.582071, 0, 0.751187, 0.389617, 0.666688, 0.707009, 0.459531, 0,  0, 0.122839, 0.748411, 0.675605, 0.365003, 0.0396101, 0, 0.135494,  0.962187, 0.419164, 0.459167, 0.661712, 0, 0.866393, 0.114304,  0.78072, 0.483805, 0.731086, 0, 0.923662, 0.998345, 0.443677,  0.149015, 0.172475, 0, 0, 0.608727, 0.776989, 0.442006, 0.712944,  0.485888, 0, 0.0285786, 0.766401, 0.347942, 0.446278, 0.893084, 0,  0.804214, 0.928778, 0.987111, 0.231373, 0.937821, 0, 0.814473,  0.206391, 0.747567, 0.206735, 0.890811, 0, 0, 0.208047, 0.30389,  0.05772, 0.718336, 0.599319, 0, 0.526901, 0.615714, 0.00539175,  0.113431, 0.498322, 0, 0.849313, 0.65745, 0.667153, 0.605238,  0.0450987, 0, 0.728673, 0.680042, 0.373866, 0.107277, 0.914199,  0}, {0.47365, 0.626298, 0.900542}, {1., 0.0233881, 0.265604,  0.322408, 0.842822, 0.305052, 1., 0.666284, 0.795507, 0.227108,  0.29966, 0.552853, 1., 0.297185, 0.377795, 0.64221, 0.885701,  0.691947, 1., 0.332696, 0.913537, 0.205659, 0.318081, 0.225419,  1.}, {0.999338, 0.732009, 0.691783, 0.324877, 0.97595, 0.466405,  0.369374, 0.482055, 0.670898, 0.800121, 0.573867, 0.254947,  0.371238, 0.247267, 0.276682}, {0.877152, 0.729028, 0.361567,  0.584736,  0.544456}, {{3, 1, 3}, {0, 2, 3}, {3, 2, 3}, {0, 2, 2}, {1, 1,  1}, {1, 2, 0}, {0, 2, 2}, {3, 0, 2}}, 0.81549, 0.155908,  0.266655, 0.319037, 0.816152}, {-7.03712, 3.68245, 4.31003,  1.79167, -3.46484, 3.68245, -7.03712, -5.55488, -3.66191, 0.784045,  4.31003, -5.55488, -7.03712, 4.47594, 0.966375, 1.79167, -3.66191,  4.47594, -7.03712, 5.6346, -3.46484, 0.784045, 0.966375,  5.6346, -7.03712}}, {{{0, 0.423899, 0.574872, 0.99416, 0.840202,  0.957494, 0, 0.205498, 0.512104, 0.169304, 0.157373, 0.63163, 0,  0.257157, 0.798066, 0.910106, 0.354948, 0.380005, 0, 0.0690384,  0.548539, 0.770212, 0.835549, 0.253548, 0, 0, 0.392632, 0.503558,  0.516512, 0.437396, 0.968733, 0, 0.928685, 0.522353, 0.597194,  0.0112388, 0.723188, 0, 0.0102483, 0.42789, 0.853866, 0.0915572,  0.753091, 0, 0.629824, 0.94376, 0.736609, 0.373086, 0.560786, 0,  0, 0.39522, 0.966397, 0.537537, 0.307238, 0.00258869, 0, 0.462839,  0.0210245, 0.869842, 0.033856, 0.534154, 0, 0.498672, 0.272648,  0.0226172, 0.810966, 0.488423, 0, 0.844757, 0.168752, 0.719409,  0.735332, 0.214933, 0, 0, 0.224992, 0.9828, 0.362246, 0.654147,  0.829772, 0, 0.0164029, 0.82471, 0.346909, 0.827183, 0.553564, 0,  0.803685, 0.477068, 0.793327, 0.0194096, 0.305013, 0, 0.20442,  0.77071, 0.208443, 0.81659, 0.359663, 0}, {0.601958, 0.489034,  0.0812575}, {1., 0.14473, 0.376966, 0.506234, 0.719011, 0.490583,  1., 0.547195, 0.489831, 0.894302, 0.143673, 0.720012, 1.,  0.936268, 0.0906164, 0.666606, 0.926685, 0.916858, 1., 0.785603,  0.462185, 0.155975, 0.708415, 0.969013, 1.}, {0.102523, 0.554017,  0.219381, 0.887756, 0.957793, 0.17705, 0.713146, 0.168745,  0.46721, 0.629856, 0.223315, 0.274443, 0.323536, 0.909844,  0.287047}, {0.183827, 0.656931, 0.98316, 0.370189,  0.398224}, {{1, 1, 1}, {2, 1, 2}, {1, 0, 0}, {0, 2, 4}, {1, 1,  3}, {3, 1, 3}, {2, 1, 1}, {1, 2, 2}}, 0.194745, 0.827185,  0.661774, 0.42921, 0.0922228}, {-172.581, 112.134, 92.4297,  2.21779, -101.743, 112.134, -172.581, -58.0857, -18.4282, -193.425,  92.4297, -58.0857, -172.581, -233.951, 164.694,  2.21779, -18.4282, -233.951, -172.581, -157.339, -101.743, -193.425,  164.694, -157.339, -172.581}}, {{{0, 0.273168, 0.442393, 0.541455,  0.13443, 0.0961178, 0, 0.729246, 0.37271, 0.66722, 0.466262,  0.505932, 0, 0.0982671, 0.343684, 0.556418, 0.218884, 0.91444, 0,  0.686753, 0.573258, 0.848696, 0.516217, 0.492008, 0, 0, 0.746073,  0.186922, 0.0870063, 0.399785, 0.472905, 0, 0.744529, 0.545551,  0.265355, 0.376787, 0.0152826, 0, 0.172841, 0.598134, 0.910525,  0.509351, 0.0745741, 0, 0.254451, 0.354108, 0.290467, 0.160134,  0.567698, 0, 0, 0.78085, 0.441771, 0.643917, 0.0756897, 0.0347764,  0, 0.254849, 0.556911, 0.675905, 0.561871, 0.51032, 0, 0.0113593,  0.41055, 0.185084, 0.495037, 0.838518, 0, 0.812415, 0.274558,  0.985686, 0.763944, 0.557965, 0, 0, 0.920451, 0.69522, 0.60381,  0.990267, 0.139601, 0, 0.253449, 0.959893, 0.914578, 0.104825,  0.9986, 0, 0.402982, 0.238673, 0.542953, 0.48828, 0.391623, 0,  0.828123, 0.357869, 0.993242, 0.553105, 0.0157075, 0}, {0.083311,  0.00755594, 0.789161}, {1., 0.457743, 0.16286, 0.312336, 0.185351,  0.467475, 1., 0.0232594, 0.0588875, 0.225458, 0.552898, 0.918435,  1., 0.0602879, 0.822475, 0.314225, 0.375482, 0.572008, 1.,  0.430852, 0.486102, 0.0176121, 0.578766, 0.877747, 1.}, {0.470394,  0.934301, 0.57121, 0.0885858, 0.0126517, 0.771441, 0.258874,  0.903235, 0.545176, 0.748181, 0.199986, 0.677777, 0.992279,  0.829747, 0.139698}, {0.855302, 0.678054, 0.454265, 0.56769,  0.424449}, {{2, 2, 2}, {2, 0, 4}, {0, 2, 4}, {2, 2, 3}, {0, 2,  1}, {3, 2, 4}, {3, 2, 3}, {0, 0, 4}}, 0.191952, 0.436653,  0.988924, 0.546702, 0.721558}, {-109.432, 48.6281, 61.99, 34.9258,  48.0025, 48.6281, -109.432, 104.549, 121.265, 89.2351, 61.99,  104.549, -109.432, 25.9853, -93.2744, 34.9258, 121.265,  25.9853, -109.432, 47.0359, 48.0025, 89.2351, -93.2744,  47.0359, -109.432}}, {{{0, 0.502352, 0.417714, 0.458117, 0.708906,  0.730911, 0, 0.15884, 0.554882, 0.16373, 0.982729, 0.958854, 0,  0.877105, 0.171451, 0.152983, 0.819156, 0.0218032, 0, 0.493397,  0.698718, 0.251466, 0.597354, 0.301445, 0, 0, 0.262065, 0.262542,  0.0506513, 0.579887, 0.759713, 0, 0.844827, 0.592535, 0.870981,  0.0288021, 0.685987, 0, 0.0376529, 0.707252, 0.0460726, 0.727133,  0.160548, 0, 0.535801, 0.89309, 0.907977, 0.138745, 0.0424041, 0,  0, 0.194372, 0.656511, 0.541391, 0.740959, 0.932307, 0, 0.393969,  0.49074, 0.161072, 0.172594, 0.549142, 0, 0.898205, 0.290091,  0.143792, 0.863155, 0.860552, 0, 0.582839, 0.0977195, 0.136022,  0.700004, 0.0470381, 0, 0, 0.20463, 0.228045, 0.561259,  0.00463397, 0.0102578, 0, 0.571534, 0.0198681, 0.263675,  0.0779506, 0.177565, 0, 0.529128, 0.102603, 0.905357, 0.628423,  0.630923, 0, 0.812512, 0.761564, 0.765268, 0.77037, 0.229673,  0}, {0.663845, 0.629246, 0.070366}, {1., 0.182635, 0.459215,  0.401201, 0.509107, 0.178001, 1., 0.448957, 0.829667, 0.489238,  0.914326, 0.371007, 1., 0.652102, 0.96011, 0.811723, 0.46565,  0.0236785, 1., 0.329188, 0.999212, 0.704086, 0.25841, 0.558817,  1.}, {0.769539, 0.0402409, 0.629164, 0.488451, 0.586904, 0.581026,  0.227963, 0.979345, 0.408903, 0.132068, 0.398297, 0.490106,  0.494577, 0.761061, 0.746195}, {0.529996, 0.682854, 0.295411,  0.722517,  0.200808}, {{0, 1, 2}, {1, 0, 0}, {2, 1, 1}, {0, 1, 1}, {0, 1,  2}, {3, 2, 0}, {3, 1, 0}, {2, 0, 0}}, 0.683642, 0.591325,  0.464106, 0.641991, 0.914103}, {-8.98705, 2.9519, -0.726693,  0.604645, 0.309326, 2.9519, -8.98705,  1.20382, -7.55559, -1.76331, -0.726693,  1.20382, -8.98705, -1.16385, -11.7551,  0.604645, -7.55559, -1.16385, -8.98705, 5.4893,  0.309326, -1.76331, -11.7551,  5.4893, -8.98705}}, {{{0, 0.551084, 0.834942, 0.15354, 0.327199,  0.970059, 0, 0.606979, 0.174195, 0.918296, 0.83799, 0.208682, 0,  0.684089, 0.423719, 0.0769291, 0.462487, 0.154093, 0, 0.740865,  0.781518, 0.739971, 0.953285, 0.0572233, 0, 0, 0.190193, 0.275864,  0.311293, 0.14312, 0.639109, 0, 0.440922, 0.157753, 0.815921,  0.66905, 0.833943, 0, 0.983558, 0.897624, 0.83106, 0.62526,  0.299469, 0, 0.473905, 0.754131, 0.162773, 0.145376, 0.73304, 0,  0, 0.972612, 0.422803, 0.192091, 0.675816, 0.782419, 0, 0.146939,  0.880798, 0.532696, 0.143311, 0.706017, 0, 0.723045, 0.716776,  0.474261, 0.872074, 0.739487, 0, 0.819152, 0.643201, 0.246813,  0.440018, 0.345246, 0, 0, 0.88907, 0.0840403, 0.294642, 0.612207,  0.916458, 0, 0.661238, 0.10255, 0.93639, 0.134038, 0.514299, 0,  0.221752, 0.403694, 0.990728, 0.808282, 0.498707, 0, 0.686918,  0.516467, 0.936208, 0.759221, 0.867766, 0}, {0.873266, 0.689395,  0.319203}, {1., 0.52252, 0.984196, 0.605355, 0.0245616, 0.910313,  1., 0.067738, 0.944117, 0.922012, 0.973923, 0.9337, 1., 0.429818,  0.70026, 0.570229, 0.942972, 0.621536, 1., 0.201552, 0.883311,  0.426505, 0.685327, 0.442332, 1.}, {0.0155444, 0.553239, 0.995933,  0.123129, 0.493024, 0.569043, 0.390578, 0.098567, 0.582711,  0.501305, 0.446461, 0.176556, 0.608788, 0.567605,  0.016643}, {0.476296, 0.0385597, 0.624633, 0.395107,  0.274744}, {{3, 2, 2}, {2, 0, 2}, {1, 1, 2}, {3, 1, 4}, {3, 1,  1}, {2, 0, 3}, {1, 0, 4}, {3, 0, 1}}, 0.155249, 0.198128,  0.70978, 0.832412, 0.139705}, {-174.546,  74.3143, -207.995, -98.7011, 220.537, 74.3143, -174.546,  209.892, -215.675, -49.4056, -207.995, 209.892, -174.546,  115.37, -16.2666, -98.7011, -215.675, 115.37, -174.546, 223.522,  220.537, -49.4056, -16.2666,  223.522, -174.546}}, {{{0, 0.64489, 0.713847, 0.709283, 0.64668,  0.0758465, 0, 0.323269, 0.610716, 0.0639688, 0.574541, 0.876808,  0, 0.434161, 0.45518, 0.00693597, 0.860165, 0.957865, 0, 0.416621,  0.382303, 0.465058, 0.683121, 0.261372, 0, 0, 0.184174, 0.755278,  0.850709, 0.121667, 0.539285, 0, 0.041431, 0.141426, 0.474987,  0.463438, 0.718162, 0, 0.53071, 0.411018, 0.888897, 0.841353,  0.0965489, 0, 0.955838, 0.881961, 0.981188, 0.138684, 0.539217, 0,  0, 0.499658, 0.51613, 0.455563, 0.277846, 0.315484, 0, 0.760852,  0.604854, 0.156178, 0.776199, 0.719421, 0, 0.463428, 0.681191,  0.312761, 0.00125896, 0.932718, 0, 0.270173, 0.423865, 0.159906,  0.836169, 0.314335, 0, 0, 0.541904, 0.178717, 0.697485, 0.775118,  0.0422456, 0, 0.662587, 0.241922, 0.497272, 0.726762, 0.901736, 0,  0.637069, 0.341093, 0.950562, 0.182315, 0.173641, 0, 0.659902,  0.637801, 0.181056, 0.240923, 0.389729, 0}, {0.213936, 0.0211504,  0.404754}, {1., 0.0753942, 0.672032, 0.842433, 0.707269, 0.300277,  1., 0.629787, 0.179846, 0.465347, 0.803005, 0.903025, 1.,  0.27811, 0.828278, 0.461911, 0.952463, 0.0957952, 1., 0.654637,  0.802009, 0.314662, 0.914739, 0.413714, 1.}, {0.41228, 0.100726,  0.893589, 0.00895969, 0.336886, 0.428694, 0.0511558, 0.301691,  0.0366089, 0.798907, 0.87131, 0.836344, 0.233604, 0.895882,  0.5932}, {0.00806573, 0.771693, 0.943419, 0.497405,  0.353429}, {{1, 0, 2}, {1, 0, 4}, {1, 0, 1}, {1, 0, 1}, {3, 2,  4}, {2, 1, 4}, {1, 1, 4}, {1, 2, 3}}, 0.969684, 0.628756,  0.582665, 0.939715, 0.557404}, {-4.44805, 8.90109,  0.608216, -0.770577, -0.647252, 8.90109, -4.44805, 0.440172,  6.76212, 1.63062, 0.608216, 0.440172, -4.44805,  6.2857, -2.31287, -0.770577, 6.76212, 6.2857, -4.44805,  1.16291, -0.647252, 1.63062, -2.31287, 1.16291, -4.44805}}};

  for (unsigned int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
    {
      double dalpha[4*5*5];
      double dlogbeta[3];
      double dgamma[5*5];
      ParameterizedNormalDistribution prior_alpha = 
        parameterized_normal_distribution (data[i].inputs.alphastddev);
      NormalDistribution prior_logbeta = 
        normal_distribution (data[i].inputs.logbetamean, 
                             data[i].inputs.logbetastddev);
      NormalDistribution prior_gamma = 
        normal_distribution (data[i].inputs.gammamean, 
                             data[i].inputs.gammastddev);

      memset (dalpha, lrand48 (), 4*5*5 * sizeof (dalpha[0]));

      for (unsigned int j = 0; j < 4; ++j)
        {
          for (unsigned int k = 0; k < 5; ++k)
            {
              data[i].inputs.alpha[j * 5 * 5 + k * 5 + k] = drand48 ();
            }
        }

      for (unsigned int k = 0; k < 5; ++k)
        {
          data[i].inputs.gamma[k * 5 + k] = drand48 ();
        }

      dqfunc (dalpha,
              dlogbeta,
              dgamma,
              data[i].inputs.alpha,
              4,
              5,
              data[i].inputs.logbeta,
              3,
              data[i].inputs.gamma,
              data[i].inputs.pz,
              data[i].inputs.ratings,
              8,
              &prior_alpha.base,
              &prior_logbeta.base,
              &prior_gamma.base,
              1);

      for (unsigned int j = 0; j < 5*5; ++j)
        {
          if (j % 5 <= (j / 5) % 5)
            {
              assert (dgamma[j] == 0.0 || 
                      (fprintf (stderr, "%u %u: %g ?= 0\n", i, j, dgamma[j]), 
                       0));
            }
          else
            {
              assert (fabs (dgamma[j] - data[i].dgamma[j]) <=
                      5e-5 * (1 + fabs (dgamma[j]) + fabs (data[i].dgamma[j])) ||
                      (fprintf (stderr, "%u %u: %g ?= %g\n", i, j, dgamma[j], data[i].dgamma[j]),
                       0));
            }
        }
    }
}

int 
main (void) 
{
  test_logprating ();
  test_dlogpratingdalpha ();
  test_dlogpratingdlogbeta ();
  test_normaldistribution ();
  test_qfunc ();
  test_qfunc_symmetric ();
  test_dqfuncdalpha ();
  test_dqfuncdalpha_symmetric ();
  test_dqfuncdlogbeta ();
  test_dqfuncdlogbeta_symmetric ();
  test_dqfuncdgamma ();
  test_dqfuncdgamma_symmetric ();

  return 0;
}
